Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
512 changes: 512 additions & 0 deletions .plans/spec-sdk-tests/01-ci-cd-integration.md

Large diffs are not rendered by default.

732 changes: 732 additions & 0 deletions .plans/spec-sdk-tests/02-coverage-reporting.md

Large diffs are not rendered by default.

408 changes: 408 additions & 0 deletions .plans/spec-sdk-tests/03-contributing-docs.md

Large diffs are not rendered by default.

475 changes: 475 additions & 0 deletions .plans/spec-sdk-tests/04-implementation-order.md

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions .plans/spec-sdk-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# OpenAPI Validation Test Suite - Implementation Plans

This directory contains detailed planning documents for the next phases of the OpenAPI validation test suite project.

## Current State (Completed)

- ✅ **Test Suite**: 147 comprehensive tests across 8 destination types
- ✅ **Test Results**: 129 passing tests (87.8% pass rate)
- ✅ **Coverage**: All destination types tested (Webhook, AWS SQS, RabbitMQ, Azure Service Bus, AWS S3, Hookdeck, AWS Kinesis, GCP Pub/Sub)
- ✅ **Documentation**: `TEST_STATUS.md` with detailed results and analysis
- ✅ **Issue Tracking**: 3 GitHub issues created for backend improvements
- ✅ **Test Infrastructure**: Factory pattern, SDK client utilities, comprehensive test suite

## Next Phases

This plan directory outlines the roadmap for enhancing the test suite with production-ready features:

### 1. [CI/CD Integration](./01-ci-cd-integration.md)
Automate test execution in GitHub Actions to ensure continuous validation of API endpoints against the OpenAPI specification.

**Key Outcomes:**
- Automated test runs on PRs and commits
- Docker-based test environment
- Test status badges
- Failure notifications

### 2. [Coverage Reporting](./02-coverage-reporting.md)
Track and visualize which OpenAPI endpoints are tested, identify gaps, and enforce coverage thresholds.

**Key Outcomes:**
- Automated coverage reports
- Visual coverage dashboards
- Coverage trend tracking
- Minimum coverage enforcement

### 3. [Contributing Documentation](./03-contributing-docs.md)
Provide clear guidelines for developers to add new tests and understand the testing architecture.

**Key Outcomes:**
- Updated CONTRIBUTING.md
- Test development guide
- Factory pattern documentation
- Development workflow examples

### 4. [Implementation Order](./04-implementation-order.md)
Recommended sequence for implementing the above phases with effort estimates and success criteria.

**Key Outcomes:**
- Prioritized roadmap
- Dependency mapping
- Effort estimates
- Success metrics

## Plan Structure

Each planning document follows this structure:

1. **Overview** - Purpose and goals
2. **Requirements** - Specific needs and constraints
3. **Technical Approach** - Implementation details
4. **Examples** - Code snippets and configurations
5. **Acceptance Criteria** - Definition of done
6. **Dependencies** - Related systems and prerequisites
7. **Risks & Considerations** - Potential challenges

## How to Use These Plans

1. **Review** - Read through each plan to understand the scope
2. **Prioritize** - Use `04-implementation-order.md` to sequence work
3. **Implement** - Follow the technical approaches and examples
4. **Validate** - Check against acceptance criteria
5. **Iterate** - Update plans based on learnings

## Related Documentation

- [`/spec-sdk-tests/README.md`](../../spec-sdk-tests/README.md) - Test suite documentation
- [`/spec-sdk-tests/TEST_STATUS.md`](../../spec-sdk-tests/TEST_STATUS.md) - Current test results
- [`/docs/apis/openapi.yaml`](../../docs/apis/openapi.yaml) - OpenAPI specification
- [`/CONTRIBUTING.md`](../../CONTRIBUTING.md) - General contribution guidelines

## Feedback and Updates

These plans are living documents. As implementation progresses:

- Update plans with new learnings
- Add implementation notes
- Document deviations from original plan
- Capture best practices discovered

---

**Last Updated**: 2025-10-12
**Status**: Ready for implementation
**Owner**: Engineering Team
13 changes: 6 additions & 7 deletions .speakeasy/workflow.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
speakeasyVersion: 1.609.0
speakeasyVersion: 1.636.3
sources:
Outpost API:
sourceNamespace: outpost-api
sourceRevisionDigest: sha256:e09cf02de047cf6d007545274c477e2a90c561074b9de170d844d9ab9ffbbca6
sourceBlobDigest: sha256:c405cfc4f2de092323a9dd68a09f7c08b563d363bce7463fc8b426d10acacf99
sourceRevisionDigest: sha256:abcb227d706ddbbb55ab9a423da413260c4d83c247616a9f6067890ff4bfa997
sourceBlobDigest: sha256:b8f43e14862cadf618bc568c76cec68ed15da6c4c7fec0541edd4671a3b26815
tags:
- latest
- speakeasy-sdk-regen-1756922597
- 0.0.1
targets:
outpost-go:
Expand All @@ -26,10 +25,10 @@ targets:
outpost-ts:
source: Outpost API
sourceNamespace: outpost-api
sourceRevisionDigest: sha256:e09cf02de047cf6d007545274c477e2a90c561074b9de170d844d9ab9ffbbca6
sourceBlobDigest: sha256:c405cfc4f2de092323a9dd68a09f7c08b563d363bce7463fc8b426d10acacf99
sourceRevisionDigest: sha256:abcb227d706ddbbb55ab9a423da413260c4d83c247616a9f6067890ff4bfa997
sourceBlobDigest: sha256:b8f43e14862cadf618bc568c76cec68ed15da6c4c7fec0541edd4671a3b26815
codeSamplesNamespace: outpost-api-typescript-code-samples
codeSamplesRevisionDigest: sha256:b1155400f3addb67547999bf99f4eb4f009470ab62329d57488f78843ff6f9b6
codeSamplesRevisionDigest: sha256:58c8e1b33a4de342b37a90c0c490a21c795e4b5c6c4f2ceef9f8c45b817a56f3
workflow:
workflowVersion: 1.0.0
speakeasyVersion: latest
Expand Down
153 changes: 150 additions & 3 deletions docs/apis/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ components:
key_template:
type: string
description: JMESPath expression for generating S3 object keys. Default is join('', [time.rfc3339_nano, '_', metadata."event-id", '.json']).
example: "join('/', [time.year, time.month, time.day, metadata.`\"event-id\"`, '.json'])"
example: 'join(''/'', [time.year, time.month, time.day, metadata."event-id", ''.json''])'
storage_class:
type: string
description: The storage class for the S3 objects (e.g., STANDARD, INTELLIGENT_TIERING, GLACIER, etc.). Defaults to "STANDARD".
Expand All @@ -284,6 +284,30 @@ components:
type: string
description: Optional AWS Session Token (for temporary credentials).
example: "AQoDYXdzEPT//////////wEXAMPLE..."
GCPPubSubConfig:
type: object
required: [project_id, topic]
properties:
project_id:
type: string
description: The GCP project ID.
example: "my-project-123"
topic:
type: string
description: The Pub/Sub topic name.
example: "events-topic"
endpoint:
type: string
description: Optional. Custom endpoint URL (e.g., localhost:8085 for emulator).
example: "pubsub.googleapis.com:443"
GCPPubSubCredentials:
type: object
required: [service_account_json]
properties:
service_account_json:
type: string
description: Service account key JSON. The entire JSON key file content as a string.
example: '{"type":"service_account","project_id":"my-project","private_key_id":"key123","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n","client_email":"my-service@my-project.iam.gserviceaccount.com"}'

# Type-Specific Destination Schemas (for Responses)
DestinationWebhook:
Expand Down Expand Up @@ -667,6 +691,60 @@ components:
credentials:
key: "AKIAIOSFODNN7EXAMPLE"
secret: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
DestinationGCPPubSub:
type: object
# Properties duplicated from DestinationBase
required: [id, type, topics, config, credentials, created_at, disabled_at]
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'disabled_at' field should not be required since it can be null when the destination is enabled. Consider removing it from the required array or making it optional.

Suggested change
required: [id, type, topics, config, credentials, created_at, disabled_at]
required: [id, type, topics, config, credentials, created_at]

Copilot uses AI. Check for mistakes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is consistent with other destination types

properties:
id:
type: string
description: Control plane generated ID or user provided ID for the destination.
example: "des_12345"
type:
type: string
description: Type of the destination.
enum: [gcp_pubsub]
example: "gcp_pubsub"
topics:
$ref: "#/components/schemas/Topics"
disabled_at:
type: string
format: date-time
nullable: true
description: ISO Date when the destination was disabled, or null if enabled.
example: null
created_at:
type: string
format: date-time
description: ISO Date when the destination was created.
example: "2024-01-01T00:00:00Z"
config:
$ref: "#/components/schemas/GCPPubSubConfig"
credentials:
$ref: "#/components/schemas/GCPPubSubCredentials"
target:
type: string
description: A human-readable representation of the destination target (project/topic). Read-only.
readOnly: true
example: "my-project-123/events-topic"
target_url:
type: string
format: url
nullable: true
description: A URL link to the destination target (GCP Console link to the topic). Read-only.
readOnly: true
example: "https://console.cloud.google.com/cloudpubsub/topic/detail/events-topic?project=my-project-123"
example:
id: "des_gcp_pubsub_123"
type: "gcp_pubsub"
topics: ["order.created", "order.updated"]
disabled_at: null
created_at: "2024-03-10T14:30:00Z"
config:
project_id: "my-project-123"
topic: "events-topic"
credentials:
service_account_json: '{"type":"service_account","project_id":"my-project-123",...}'

# Polymorphic Destination Schema (for Responses)
Destination:
Expand All @@ -678,6 +756,7 @@ components:
- $ref: "#/components/schemas/DestinationAWSKinesis"
- $ref: "#/components/schemas/DestinationAzureServiceBus"
- $ref: "#/components/schemas/DestinationAWSS3"
- $ref: "#/components/schemas/DestinationGCPPubSub"
discriminator:
propertyName: type
mapping:
Expand All @@ -688,6 +767,7 @@ components:
aws_kinesis: "#/components/schemas/DestinationAWSKinesis"
azure_servicebus: "#/components/schemas/DestinationAzureServiceBus"
aws_s3: "#/components/schemas/DestinationAWSS3"
gcp_pubsub: "#/components/schemas/DestinationGCPPubSub"

DestinationCreateWebhook:
type: object
Expand Down Expand Up @@ -817,6 +897,24 @@ components:
$ref: "#/components/schemas/AWSS3Config"
credentials:
$ref: "#/components/schemas/AWSS3Credentials"
DestinationCreateGCPPubSub:
type: object
required: [type, topics, config, credentials]
properties:
id:
type: string
description: Optional user-provided ID. A UUID will be generated if empty.
example: "user-provided-id"
type:
type: string
description: Type of the destination. Must be 'gcp_pubsub'.
enum: [gcp_pubsub]
topics:
$ref: "#/components/schemas/Topics"
config:
$ref: "#/components/schemas/GCPPubSubConfig"
credentials:
$ref: "#/components/schemas/GCPPubSubCredentials"

# Polymorphic Destination Creation Schema (for Request Bodies)
DestinationCreate:
Expand All @@ -828,6 +926,7 @@ components:
- $ref: "#/components/schemas/DestinationCreateAWSKinesis"
- $ref: "#/components/schemas/DestinationCreateAzureServiceBus"
- $ref: "#/components/schemas/DestinationCreateAWSS3"
- $ref: "#/components/schemas/DestinationCreateGCPPubSub"
discriminator:
propertyName: type
mapping:
Expand All @@ -838,6 +937,7 @@ components:
aws_kinesis: "#/components/schemas/DestinationCreateAWSKinesis"
azure_servicebus: "#/components/schemas/DestinationCreateAzureServiceBus"
aws_s3: "#/components/schemas/DestinationCreateAWSS3"
gcp_pubsub: "#/components/schemas/DestinationCreateGCPPubSub"

# Type-Specific Destination Update Schemas (for Request Bodies)
WebhookCredentialsUpdate:
Expand Down Expand Up @@ -905,6 +1005,16 @@ components:
$ref: "#/components/schemas/AWSKinesisConfig" # stream_name/region required here, but PATCH means optional
credentials:
$ref: "#/components/schemas/AWSKinesisCredentials" # key/secret required here, but PATCH means optional
DestinationUpdateAzureServiceBus:
type: object
# Properties duplicated from DestinationUpdateBase
properties:
topics:
$ref: "#/components/schemas/Topics"
config:
$ref: "#/components/schemas/AzureServiceBusConfig" # name required here, but PATCH means optional
credentials:
$ref: "#/components/schemas/AzureServiceBusCredentials" # connection_string required here, but PATCH means optional

DestinationUpdateAWSS3:
type: object
Expand All @@ -916,6 +1026,16 @@ components:
$ref: "#/components/schemas/AWSS3Config" # bucket/region required here, but PATCH means optional
credentials:
$ref: "#/components/schemas/AWSS3Credentials" # key/secret required here, but PATCH means optional
DestinationUpdateGCPPubSub:
type: object
# Properties duplicated from DestinationUpdateBase
properties:
topics:
$ref: "#/components/schemas/Topics"
config:
$ref: "#/components/schemas/GCPPubSubConfig" # project_id/topic required here, but PATCH means optional
credentials:
$ref: "#/components/schemas/GCPPubSubCredentials" # service_account_json required here, but PATCH means optional

# Polymorphic Destination Update Schema (for Request Bodies)
DestinationUpdate:
Expand All @@ -925,7 +1045,9 @@ components:
- $ref: "#/components/schemas/DestinationUpdateRabbitMQ"
- $ref: "#/components/schemas/DestinationUpdateHookdeck"
- $ref: "#/components/schemas/DestinationUpdateAWSKinesis"
- $ref: "#/components/schemas/DestinationUpdateAzureServiceBus"
- $ref: "#/components/schemas/DestinationUpdateAWSS3"
- $ref: "#/components/schemas/DestinationUpdateGCPPubSub"
# Event Schemas
PublishRequest:
type: object
Expand Down Expand Up @@ -996,10 +1118,15 @@ components:
example: "2024-01-01T00:00:00Z"
metadata:
type: object
nullable: true
description: Key-value string pairs of metadata associated with the event.
additionalProperties:
type: string
example: { "source": "crm" }
status:
type: string
enum: [success, failed]
example: "success"
data:
type: object
description: Freeform JSON data of the event.
Expand Down Expand Up @@ -1338,11 +1465,31 @@ paths:
schema:
oneOf:
- type: string
enum: [webhook, aws_sqs, rabbitmq, hookdeck, aws_kinesis, aws_s3]
enum:
[
webhook,
aws_sqs,
rabbitmq,
hookdeck,
aws_kinesis,
azure_servicebus,
aws_s3,
gcp_pubsub,
]
- type: array
items:
type: string
enum: [webhook, aws_sqs, rabbitmq, hookdeck, aws_kinesis, aws_s3]
enum:
[
webhook,
aws_sqs,
rabbitmq,
hookdeck,
aws_kinesis,
azure_servicebus,
aws_s3,
gcp_pubsub,
]
description: Filter destinations by type(s).
- name: topics
in: query
Expand Down
7 changes: 7 additions & 0 deletions examples/demos/nodejs/src/portal-urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ const main = async () => {
const portalUrl = await outpost.getPortalURL(org.id);
console.log(`Portal URL for ${org.id}:`, portalUrl);
}

try {
const portalUrl = await outpost.getPortalURL("test-tenant");
console.log(`Portal URL for test-tenant:`, portalUrl);
} catch (error) {
console.error(`Failed to create portal for test-tenant:`, error);
}
};

main()
Expand Down
Loading