diff --git a/docs-cms/adr/adr-000-template.md b/docs-cms/adr/adr-000-template.md index 902b0093..73a120de 100644 --- a/docs-cms/adr/adr-000-template.md +++ b/docs-cms/adr/adr-000-template.md @@ -1,4 +1,33 @@ --- +<<<<<<< HEAD +date: YYYY-MM-DD +deciders: +- Names/Roles +doc_uuid: 7bd8659a-a8e7-4fb1-854d-daf5741c19d3 +project_id: prism-data-layer +status: +- Proposed | Accepted | Deprecated | Superseded by ADR-YYY +tags: +- backend +- proxy +- security +- performance +- testing +title: 'ADR-XXX: [Short Title]' +--- + +## Context + +What is the issue we're facing and the context around it? What are we trying to achieve? + +## Decision + +What is the change we're proposing/announcing? + +## Rationale + +Why did we choose this approach? What alternatives did we consider? +======= # REQUIRED FIELDS - ALL must be present for validation to pass title: 'ADR-XXX: Title Here' # Must start with "ADR-XXX:" where XXX is 3-digit number status: Proposed # One of: Proposed | Accepted | Implemented | Deprecated | Superseded @@ -57,10 +86,42 @@ What factors did we consider? (Optional: use weighted scoring) - **Performance** (weight: X%): Description - **Developer Experience** (weight: Y%): Description - **Cost/Maintenance** (weight: Z%): Description +>>>>>>> origin/main ### Alternatives Considered 1. **Alternative 1**: Description +<<<<<<< HEAD + - Pros: ... + - Cons: ... + - Rejected because: ... + +2. **Alternative 2**: Description + - Pros: ... + - Cons: ... + - Rejected because: ... + +## Consequences + +### Positive + +- What becomes easier +- What capabilities do we gain + +### Negative + +- What becomes harder +- What trade-offs are we making + +### Neutral + +- What stays the same +- What new considerations emerge + +## Implementation Notes + +Key technical details, gotchas, or migration steps. +======= - **Pros**: - Benefit 1 - Benefit 2 @@ -105,11 +166,24 @@ What are the implications of this decision? Optional section for implementation details, milestones, or technical specifics. Key technical details, gotchas, or migration steps: +>>>>>>> origin/main ```rust // Example code if relevant ``` +<<<<<<< HEAD +## References + +- [Link to related ADRs] +- [Link to external resources] +- [Link to requirements docs] + +## Revision History + +- YYYY-MM-DD: Initial draft +- YYYY-MM-DD: Accepted after review +======= **Migration Steps** (if applicable): 1. Step one 2. Step two @@ -128,3 +202,4 @@ Key technical details, gotchas, or migration steps: - YYYY-MM-DD: Initial draft (Author Name) - YYYY-MM-DD: Accepted after review (Deciders) - YYYY-MM-DD: Amended with clarification (Author Name) +>>>>>>> origin/main diff --git a/docs-cms/adr/adr-023-grpc-first-interface-design.md b/docs-cms/adr/adr-023-grpc-first-interface-design.md index 11fbd893..04ba37e7 100644 --- a/docs-cms/adr/adr-023-grpc-first-interface-design.md +++ b/docs-cms/adr/adr-023-grpc-first-interface-design.md @@ -97,13 +97,23 @@ Use **gRPC as the primary interface** for Prism data access layer: │ Go Client │ │ Rust Client │ │ (generated code) │ │ (generated code) │ └───────────────────┘ └───────────────────┘ +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ### Service Organization Each access pattern gets its own service: +<<<<<<< HEAD +``` + +======= ```protobuf +>>>>>>> origin/main // proto/prism/session/v1/session_service.proto service SessionService { rpc CreateSession(CreateSessionRequest) returns (CreateSessionResponse); @@ -137,13 +147,22 @@ service TransactService { rpc Write(WriteRequest) returns (WriteResponse); rpc Transaction(stream TransactRequest) returns (stream TransactResponse); } +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ### Streaming Patterns **Server streaming** (pagination, pub/sub): +<<<<<<< HEAD +``` +======= ```protobuf +>>>>>>> origin/main service ReaderService { // Server streams pages to client @@ -154,11 +173,19 @@ service ReaderService { }; } } +<<<<<<< HEAD + +```text + +``` + +======= ``` **Server implementation:** ```rust +>>>>>>> origin/main // Server implementation async fn read(&self, req: Request) -> Result, Status> { let (tx, rx) = mpsc::channel(100); @@ -177,33 +204,58 @@ async fn read(&self, req: Request) -> Result>>>>>> origin/main service TransactService { // Client streams write batches rpc BatchWrite(stream WriteRequest) returns (WriteResponse); } +<<<<<<< HEAD + +```text + +**Bidirectional streaming** (pub/sub with acks): +``` +======= ``` **Bidirectional streaming** (pub/sub with acks): ```protobuf +>>>>>>> origin/main service PubSubService { // Client subscribes, server streams events, client sends acks rpc Stream(stream ClientMessage) returns (stream ServerMessage); } +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ### Error Handling Use gRPC status codes: +<<<<<<< HEAD +``` +======= ```rust +>>>>>>> origin/main use tonic::{Code, Status}; @@ -221,11 +273,20 @@ return Err(Status::deadline_exceeded("operation timed out")); // Permission denied return Err(Status::permission_denied("insufficient permissions")); +<<<<<<< HEAD + +```text + +Structured error details: + +``` +======= ``` Structured error details: ```protobuf +>>>>>>> origin/main import "google/rpc/error_details.proto"; @@ -234,13 +295,22 @@ message ErrorInfo { string domain = 2; map metadata = 3; } +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ### Metadata and Context Use gRPC metadata for cross-cutting concerns: +<<<<<<< HEAD +``` +======= ```rust +>>>>>>> origin/main // Server: extract session token from metadata let session_token = req.metadata() @@ -254,7 +324,12 @@ request.metadata_mut().insert( "x-session-token", session_token.parse().unwrap(), ); +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main Common metadata: - `x-session-token`: Session identifier @@ -265,34 +340,62 @@ Common metadata: ### Performance Optimizations **Connection pooling:** +<<<<<<< HEAD +``` + +======= ```rust +>>>>>>> origin/main // Reuse connections let channel = Channel::from_static("http://localhost:8980") .connect_lazy(); let client = QueueServiceClient::new(channel.clone()); +<<<<<<< HEAD + +```text + +**Compression:** +``` + +======= ``` **Compression:** ```rust +>>>>>>> origin/main // Enable gzip compression let channel = Channel::from_static("http://localhost:8980") .http2_keep_alive_interval(Duration::from_secs(30)) .http2_adaptive_window(true) .connect_lazy(); +<<<<<<< HEAD + +```text + +**Timeouts:** +``` + +======= ``` **Timeouts:** ```protobuf +>>>>>>> origin/main service QueueService { rpc Publish(PublishRequest) returns (PublishResponse) { option (google.api.method_signature) = "timeout=5s"; } } +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ### Alternatives Considered @@ -344,7 +447,12 @@ service QueueService { ### Server Implementation (Rust) +<<<<<<< HEAD +``` + +======= ```rust +>>>>>>> origin/main // proxy/src/main.rs use tonic::transport::Server; @@ -365,11 +473,21 @@ async fn main() -> Result<()> { Ok(()) } +<<<<<<< HEAD + +```text + +### Client Implementation (Go) + +``` + +======= ``` ### Client Implementation (Go) ```go +>>>>>>> origin/main // Client connection conn, err := grpc.Dial( "localhost:8980", @@ -390,11 +508,20 @@ resp, err := client.Publish(ctx, &queue.PublishRequest{ Payload: data, }) +<<<<<<< HEAD +```text + +### Testing with grpcurl + +``` + +======= ``` ### Testing with grpcurl ```bash +>>>>>>> origin/main # List services grpcurl -plaintext localhost:8980 list @@ -404,11 +531,20 @@ grpcurl -plaintext localhost:8980 describe prism.queue.v1.QueueService # Make request grpcurl -plaintext -d '{"topic":"events","payload":"dGVzdA=="}' \ localhost:8980 prism.queue.v1.QueueService/Publish +<<<<<<< HEAD + +```text + +### Code Generation + +``` +======= ``` ### Code Generation ```bash +>>>>>>> origin/main # Generate Rust code buf generate --template proxy/buf.gen.rust.yaml @@ -418,7 +554,12 @@ buf generate --template tools/buf.gen.go.yaml # Generate Python code buf generate --template clients/python/buf.gen.python.yaml +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ## References diff --git a/docs-cms/adr/adr-037-kubernetes-operator.md b/docs-cms/adr/adr-037-kubernetes-operator.md index 58eefb16..d6a2fc93 100644 --- a/docs-cms/adr/adr-037-kubernetes-operator.md +++ b/docs-cms/adr/adr-037-kubernetes-operator.md @@ -179,6 +179,44 @@ The following CRDs are planned for future implementation: ### Operator Architecture (Implemented) +<<<<<<< HEAD +┌──────────────────────────────────────────────────────────┐ +│ Kubernetes Cluster │ +│ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Prism Operator (Controller) │ │ +│ │ │ │ +│ │ Watches: │ │ +│ │ - PrismNamespace CRDs │ │ +│ │ - PrismShard CRDs │ │ +│ │ - PrismPlugin CRDs │ │ +│ │ │ │ +│ │ Reconciles: │ │ +│ │ 1. Creates/updates Prism Deployments │ │ +│ │ 2. Provisions PVCs for SQLite config (ADR-036) │ │ +│ │ 3. Deploys plugin sidecars │ │ +│ │ 4. Updates Services, Ingress │ │ +│ │ 5. Syncs namespace config to Prism instances │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌──────────────────┐ ┌──────────────────┐ │ +│ │ PrismShard: │ │ PrismShard: │ │ +│ │ playback-live │ │ analytics-batch │ │ +│ │ │ │ │ │ +│ │ ┌────────────┐ │ │ ┌────────────┐ │ │ +│ │ │ Prism Pod │ │ │ │ Prism Pod │ │ │ +│ │ │ replicas:5 │ │ │ │ replicas:3 │ │ │ +│ │ └────────────┘ │ │ └────────────┘ │ │ +│ │ ┌────────────┐ │ │ ┌────────────┐ │ │ +│ │ │ Plugins │ │ │ │ Plugins │ │ │ +│ │ │ (sidecars) │ │ │ │ (sidecars) │ │ │ +│ │ └────────────┘ │ │ └────────────┘ │ │ +│ └──────────────────┘ └──────────────────┘ │ +└──────────────────────────────────────────────────────────┘ + +======= +>>>>>>> origin/main ```text ┌──────────────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ @@ -264,19 +302,33 @@ See `prism-operator/README.md` for complete documentation. ### Why Custom Operator vs Raw Kubernetes? **Without Operator** (raw Kubernetes manifests): +<<<<<<< HEAD +``` + +======= ```text +>>>>>>> origin/main # Must manually define: - Deployment for each shard - StatefulSet for SQLite persistence - Services for each shard - ConfigMaps for namespace configs (must sync manually!) - Plugin sidecar injection (manual, error-prone) +<<<<<<< HEAD + +```text + +**With Operator**: +``` + +======= ``` **With Operator**: ```yaml +>>>>>>> origin/main # Just define: apiVersion: prism.io/v1alpha1 kind: PrismNamespace @@ -286,7 +338,12 @@ spec: backend: postgres pattern: keyvalue # Operator handles the rest! +<<<<<<< HEAD + +```text +======= ``` +>>>>>>> origin/main ### Compared to Alternatives