first commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-02
|
||||
@@ -0,0 +1,79 @@
|
||||
## Context
|
||||
|
||||
`platform/` already contains typed domain resources, DTO contracts, model projections, validators, repositories, and `service.Core` workflows for the first platform resources. The current executable only exposes `/healthz`, so frontend, run, and plugin changes cannot yet rely on HTTP behavior for users, game plugins, server instances, AI providers, run endpoints, jobs, artifacts, log streams, or audit events.
|
||||
|
||||
This change stays inside `platform/` and implements the first HTTP adapter layer over the existing core service. It must preserve the repository structure rules: handlers belong in `api/`, request/response DTOs in `dto/`, domain rules in `domain/` and `validator/`, and storage concerns in `repo/` or future persistence packages.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Expose create, list, and detail HTTP routes for core platform resources.
|
||||
- Keep handlers as adapters that decode named DTOs, call `service.Core`, and encode named DTO responses.
|
||||
- Return deterministic JSON error responses for malformed JSON, validation failures, duplicate IDs, missing resources, and unexpected failures.
|
||||
- Preserve AI provider redaction by returning `apiKeyRef` only and never raw API key material.
|
||||
- Make router construction injectable for tests and future persistence while retaining an in-memory default for local development.
|
||||
- Update `platform/api/routes.md` to reflect implemented routes.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- No authentication, session, RBAC, or authorization engine.
|
||||
- No SQL database, migrations, or external persistence dependency.
|
||||
- No frontend or run-side implementation.
|
||||
- No run job claim/ack/result protocol implementation beyond platform-side job resource creation and query.
|
||||
- No plugin page bridge implementation, AI invocation endpoint, file content transfer, log body ingest, or artifact chunk transfer.
|
||||
- No billing, cloud host sales, agent-provider/cloud-provider workflows, or unrelated SaaS marketplace features.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Use `net/http` ServeMux with explicit method dispatch
|
||||
|
||||
The platform will keep using the Go standard library. Route wiring will use `http.ServeMux` path patterns, `PathValue` for detail routes, and explicit method dispatch inside resource handlers so unsupported methods can return the named JSON error DTO.
|
||||
|
||||
Alternative considered: adding a third-party router. Rejected because the API surface is still small and the current module has no external runtime dependencies.
|
||||
|
||||
### Decision 2: Router accepts `service.Core`
|
||||
|
||||
`api.NewRouter()` will build the current in-memory service for local execution, while `api.NewRouterWithCore(core service.Core)` will allow tests and later persistence changes to provide a service implementation.
|
||||
|
||||
Alternative considered: constructing repositories directly inside every handler. Rejected because it hides storage choices in transport code and bypasses the service layer that already owns cross-resource invariants.
|
||||
|
||||
### Decision 3: DTO package owns request conversion and API envelopes
|
||||
|
||||
Create-request DTOs will expose `ToDomain()` helpers. Response DTOs and list/error envelopes will remain named structs under `platform/dto` so handlers do not define request/response shapes inline.
|
||||
|
||||
Alternative considered: constructing ad hoc response maps in handlers. Rejected because API contracts must remain discoverable and testable.
|
||||
|
||||
### Decision 4: Handlers map service errors to stable HTTP errors
|
||||
|
||||
Handlers will translate `validator.ValidationError` to `400`, malformed JSON to `400`, `repo.ErrNotFound` to `404`, `repo.ErrDuplicate` to `409`, and unexpected errors to `500`. All errors will use `dto.ErrorResponse`.
|
||||
|
||||
Alternative considered: returning plain-text `http.Error`. Rejected because clients need predictable JSON responses and AGENTS.md requires named error DTOs.
|
||||
|
||||
### Decision 5: Implement metadata routes only for logs and artifacts
|
||||
|
||||
This change implements log stream metadata and artifact metadata resources. Chunk upload/download, durable log ingest, tail transport, and storage adapters remain future changes because they affect run communication channels and transfer backpressure.
|
||||
|
||||
Alternative considered: implementing chunk and ingest endpoints now. Rejected because the delivery stream has separate changes for run channels, logs, and artifacts.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] In-memory default storage loses data on restart. Mitigation: document it as local development wiring and keep router injection ready for future persistence.
|
||||
- [Risk] Create/list/get routes are narrower than the full route catalog. Mitigation: document deferred lifecycle, chunk, ingest, and plugin bridge behavior explicitly in `platform/api/routes.md`.
|
||||
- [Risk] Query filter values are string-based and rely on domain enum strings. Mitigation: keep filters narrow and let create/update validation remain in the service and validator layers.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Add DTO conversion helpers, list envelopes, and error DTOs.
|
||||
2. Add API router wiring and handlers over `service.Core`.
|
||||
3. Update route catalog documentation.
|
||||
4. Add focused handler tests for route behavior, validation/error mapping, and AI provider redaction.
|
||||
5. Verify with `go test ./...` from `platform/`, `scripts/check-structure.sh`, and strict OpenSpec validation.
|
||||
|
||||
Rollback before dependent changes is removal of the API handler additions and this OpenSpec change. After frontend, run, or plugin changes consume these routes, rollback must be handled through a new OpenSpec change.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Which authentication/session mechanism will wrap these routes first?
|
||||
- Which persistent repository implementation should replace the in-memory default?
|
||||
- Which API pagination and sorting contract should be introduced once lists can grow beyond development-scale data?
|
||||
@@ -0,0 +1,30 @@
|
||||
## Why
|
||||
|
||||
The platform backend has typed core resources and service workflows, but clients still cannot exercise them through HTTP. This change adds the first platform API surface so later frontend, run, and plugin work can depend on stable handler behavior instead of calling services directly.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add HTTP route handlers for core platform resources using the existing domain, DTO, validator, repository, and service packages.
|
||||
- Support create, list, and detail workflows for users, AI providers, game management plugins, server instances, run endpoints, jobs, artifacts, log streams, and audit events.
|
||||
- Return JSON error responses for malformed requests, validation failures, duplicates, and missing resources.
|
||||
- Preserve AI provider redaction by returning only API key references and never raw provider keys.
|
||||
- Wire the platform router to an in-memory service instance for local development while keeping handlers injectable for tests and future persistence.
|
||||
- Update route catalog documentation to reflect the implemented API paths.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `platform-api-surface`: HTTP API handlers, route wiring, request decoding, response encoding, and error behavior for core platform resources.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- None.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affects `platform/` only.
|
||||
- Adds platform API handler code and focused handler tests.
|
||||
- Extends DTO helpers for request-to-domain conversion and JSON error response contracts.
|
||||
- Uses only Go standard library HTTP routing and the existing in-memory core service.
|
||||
- Does not add authentication, authorization, SQL persistence, frontend behavior, run executor behavior, billing, cloud host sales, or direct plugin/run access.
|
||||
@@ -0,0 +1,82 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Core resource HTTP routes are implemented
|
||||
The platform SHALL expose HTTP JSON routes for create, list, and detail workflows for users, AI providers, game management plugins, server instances, run endpoints, jobs, artifacts, log streams, and audit events.
|
||||
|
||||
#### Scenario: Resource is created through API
|
||||
- **WHEN** a valid create request is posted to a core resource collection route
|
||||
- **THEN** the platform MUST persist the resource through `service.Core` and return `201` with the corresponding named response DTO
|
||||
|
||||
#### Scenario: Resource list is requested
|
||||
- **WHEN** a client sends `GET` to a core resource collection route
|
||||
- **THEN** the platform MUST return `200` with a named list response DTO containing resources from `service.Core`
|
||||
|
||||
#### Scenario: Resource detail is requested
|
||||
- **WHEN** a client sends `GET` to a core resource detail route with an existing resource ID
|
||||
- **THEN** the platform MUST return `200` with the corresponding named response DTO
|
||||
|
||||
### Requirement: API handlers use centralized DTO and service contracts
|
||||
The platform SHALL keep API request, response, list, and error contracts in `platform/dto` and SHALL call `service.Core` for resource workflows.
|
||||
|
||||
#### Scenario: Handler decodes request body
|
||||
- **WHEN** an API handler accepts a request body
|
||||
- **THEN** it MUST decode into a named DTO type from `platform/dto` and convert that DTO to a named domain type before calling `service.Core`
|
||||
|
||||
#### Scenario: Handler returns response body
|
||||
- **WHEN** an API handler returns a success or error response
|
||||
- **THEN** it MUST encode a named DTO response type and MUST NOT define response structs inside handler functions
|
||||
|
||||
### Requirement: API errors are stable JSON responses
|
||||
The platform SHALL return named JSON error DTOs for malformed requests, validation failures, duplicate resources, missing resources, unsupported methods, and unexpected failures.
|
||||
|
||||
#### Scenario: Invalid JSON is submitted
|
||||
- **WHEN** a client posts malformed JSON to a core resource route
|
||||
- **THEN** the platform MUST return `400` with a JSON error response
|
||||
|
||||
#### Scenario: Validation fails
|
||||
- **WHEN** a create request violates validator or service invariants
|
||||
- **THEN** the platform MUST return `400` with a JSON error response and MUST NOT persist the resource
|
||||
|
||||
#### Scenario: Duplicate resource is submitted
|
||||
- **WHEN** a create request uses an ID that already exists
|
||||
- **THEN** the platform MUST return `409` with a JSON error response
|
||||
|
||||
#### Scenario: Missing resource is requested
|
||||
- **WHEN** a client requests a resource ID that does not exist
|
||||
- **THEN** the platform MUST return `404` with a JSON error response
|
||||
|
||||
### Requirement: AI provider API preserves credential redaction
|
||||
The AI provider API SHALL return redacted provider response DTOs that include secret references only and never raw API keys.
|
||||
|
||||
#### Scenario: AI provider is created through API
|
||||
- **WHEN** a valid AI provider create request is posted
|
||||
- **THEN** the platform MUST return an `AIProviderResponse` containing `apiKeyRef` and MUST NOT include raw API key fields
|
||||
|
||||
#### Scenario: Raw AI key is submitted as key reference
|
||||
- **WHEN** an AI provider create request includes raw key material in `apiKeyRef`
|
||||
- **THEN** the platform MUST reject the request with `400` and MUST NOT persist the provider
|
||||
|
||||
### Requirement: Router is injectable and local-development ready
|
||||
The platform SHALL provide router construction that accepts a core service for tests and future persistence, and a default router that uses the in-memory core service for local development.
|
||||
|
||||
#### Scenario: Local platform process starts
|
||||
- **WHEN** `cmd/platform` creates the default router
|
||||
- **THEN** the router MUST expose `/healthz` and all implemented core API routes backed by an in-memory `service.Core`
|
||||
|
||||
#### Scenario: Tests provide a service
|
||||
- **WHEN** tests call router construction with an explicit `service.Core`
|
||||
- **THEN** handlers MUST use that service instance for all route operations
|
||||
|
||||
### Requirement: Route catalog matches implemented API surface
|
||||
The platform route catalog SHALL identify implemented core API routes and clearly distinguish deferred run transport, log ingest, artifact chunk, plugin bridge, and AI invocation behavior.
|
||||
|
||||
#### Scenario: Contributor inspects API catalog
|
||||
- **WHEN** a contributor opens `platform/api/routes.md`
|
||||
- **THEN** the file MUST list the implemented create, list, and detail routes and MUST identify deferred behavior as not implemented by this change
|
||||
|
||||
### Requirement: API handler tests verify surface behavior
|
||||
The platform SHALL include API tests covering successful create/list/detail workflows, JSON error mapping, dependency validation, duplicate handling, missing resources, and AI provider redaction.
|
||||
|
||||
#### Scenario: Platform API tests run
|
||||
- **WHEN** `go test ./...` is executed inside `platform/`
|
||||
- **THEN** tests MUST verify the implemented HTTP API behavior without external services or a database
|
||||
@@ -0,0 +1,30 @@
|
||||
## 1. DTO And Router Contracts
|
||||
|
||||
- [x] 1.1 Add named DTO list/error response contracts and request-to-domain conversion helpers for core resource create requests.
|
||||
- [x] 1.2 Add injectable platform router construction that wires health and core API routes through `service.Core` with an in-memory default.
|
||||
|
||||
## 2. Core API Handlers
|
||||
|
||||
- [x] 2.1 Implement users, AI providers, game plugins, server instances, and run endpoints create/list/detail handlers.
|
||||
- [x] 2.2 Implement jobs, artifacts, log streams, and audit events create/list/detail handlers.
|
||||
- [x] 2.3 Implement shared JSON decode, encode, method, and error mapping behavior using named DTO responses.
|
||||
- [x] 2.4 Update `platform/api/routes.md` to identify implemented routes and deferred transport/bridge behavior.
|
||||
|
||||
## 3. API Tests
|
||||
|
||||
- [x] 3.1 Add handler tests for successful create/list/detail workflows and query filters.
|
||||
- [x] 3.2 Add handler tests for malformed JSON, validation errors, duplicates, missing resources, dependency failures, and AI provider redaction.
|
||||
|
||||
## 4. Verification
|
||||
|
||||
- [x] 4.1 Run `go test ./...` from `platform/` and record evidence.
|
||||
- [x] 4.2 Run `scripts/check-structure.sh` and record evidence.
|
||||
- [x] 4.3 Run `openspec validate implement-platform-api-surface --strict` and record evidence.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `go test ./api`: passed.
|
||||
- `go test ./dto`: passed.
|
||||
- `go test ./...` from `platform/`: passed.
|
||||
- `scripts/check-structure.sh`: passed.
|
||||
- `openspec validate implement-platform-api-surface --strict`: passed.
|
||||
Reference in New Issue
Block a user