feat(workspace): workspace domain — schema, store, routes, daemon linking#82
feat(workspace): workspace domain — schema, store, routes, daemon linking#82
Conversation
… linking New domain package `packages/domains/workspace/` with Zod schemas for workspace entities (monorepo/multi-repo), CRUD routes via @hono/zod-openapi, in-memory store, and 21 unit tests for schema validation. Adds optional `workspace` field to daemon domain (CreateDaemonRequestSchema, DaemonListItemSchema, StoredDaemon) to link daemons to workspaces. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 4 minutes and 33 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a new workspace domain package with schemas, store, routes, and tests; extends the daemon domain by adding an optional Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Deploying getpaws with
|
| Latest commit: |
ef779fd
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://bc5d688f.getpaws-6m4.pages.dev |
| Branch Preview URL: | https://feat-workspace-domain.getpaws-6m4.pages.dev |
…domains) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
packages/domains/workspace/src/routes.ts (1)
70-83: UsePATCHfor partial updates (or makePUTbody full-replacement).Line 71 declares
put, but the body schema is partial-update shaped. Preferpatchto match API semantics and client expectations.Proposed adjustment
export const updateWorkspaceRoute = createRoute({ - method: 'put', + method: 'patch', path: '/v1/workspaces/{id}',🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/domains/workspace/src/routes.ts` around lines 70 - 83, The route definition updateWorkspaceRoute currently uses method 'put' but validates against a partial-update schema (UpdateWorkspaceRequestSchema); change the HTTP method to 'patch' in the createRoute call so the route semantics match the partial body schema (or alternatively replace UpdateWorkspaceRequestSchema with a full-replacement schema if you intend PUT semantics); ensure the method string in createRoute and any related route docs/tags remain consistent with the chosen behavior.packages/domains/workspace/src/types.ts (1)
5-5: Tightenrepovalidation to match the documentedowner/reposhape.Line 5 currently accepts any non-empty string, so malformed repository identifiers pass validation.
Proposed fix
- repo: z.string().min(1), // "owner/repo" + repo: z + .string() + .regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/, 'Expected "owner/repo"'),As per coding guidelines, "Use Zod for all external data validation: API requests, config files, and environment variables via
@t3-oss/env-core."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/domains/workspace/src/types.ts` at line 5, The current zod schema for the repo field accepts any non-empty string; change the repo validator in types.ts to enforce the "owner/repo" shape by replacing repo: z.string().min(1) with a z.string() that uses a regex check for a single slash-separated owner and repo (e.g., allowed characters like alphanumerics, hyphen, underscore, dot) and a custom error message; reference the repo symbol in the schema to locate and update this validator so malformed identifiers fail validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/domains/daemon/src/store.ts`:
- Line 13: StoredDaemon in the control-plane store is missing the workspace
field so workspace is dropped; update the StoredDaemon interface to include
workspace?: string | undefined, modify the in-memory store create()
implementation to set workspace: request.workspace when building the stored
object in the create() method, and update the SQLite store insert statement to
include the workspace column and bind request.workspace in the values for the
insert (adjust the INSERT SQL and parameter list in the SQLite store
implementation accordingly).
In `@packages/domains/workspace/src/types.ts`:
- Around line 67-69: The refine on UpdateWorkspaceRequestSchema currently only
checks Object.keys(data).length, allowing objects like { name: undefined } to
pass; change the predicate used in the .refine call to verify at least one value
is not undefined (e.g., use Object.values(data).some(value => value !==
undefined)) so that payloads with only undefined fields are rejected and the
existing error message remains accurate.
In `@packages/domains/workspace/tsconfig.json`:
- Line 7: Remove the package-level compilerOptions.types entry from the
tsconfig: locate the tsconfig JSON (where "types": [] is present) and delete the
"types" property entirely so the package no longer overrides global type
inclusion; ensure no other per-package tsconfig files set compilerOptions.types
either and keep the rest of the compilerOptions intact.
---
Nitpick comments:
In `@packages/domains/workspace/src/routes.ts`:
- Around line 70-83: The route definition updateWorkspaceRoute currently uses
method 'put' but validates against a partial-update schema
(UpdateWorkspaceRequestSchema); change the HTTP method to 'patch' in the
createRoute call so the route semantics match the partial body schema (or
alternatively replace UpdateWorkspaceRequestSchema with a full-replacement
schema if you intend PUT semantics); ensure the method string in createRoute and
any related route docs/tags remain consistent with the chosen behavior.
In `@packages/domains/workspace/src/types.ts`:
- Line 5: The current zod schema for the repo field accepts any non-empty
string; change the repo validator in types.ts to enforce the "owner/repo" shape
by replacing repo: z.string().min(1) with a z.string() that uses a regex check
for a single slash-separated owner and repo (e.g., allowed characters like
alphanumerics, hyphen, underscore, dot) and a custom error message; reference
the repo symbol in the schema to locate and update this validator so malformed
identifiers fail validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cd950ab4-55d2-46eb-9cd0-80046544aee0
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (11)
packages/domains/daemon/src/store.tspackages/domains/daemon/src/types.tspackages/domains/workspace/package.jsonpackages/domains/workspace/src/index.tspackages/domains/workspace/src/routes.tspackages/domains/workspace/src/store.tspackages/domains/workspace/src/types.test.tspackages/domains/workspace/src/types.tspackages/domains/workspace/tsconfig.jsonpackages/domains/workspace/vitest.config.tstsconfig.json
| status: DaemonStatus; | ||
| snapshot: string; | ||
| trigger: Trigger; | ||
| workspace?: string | undefined; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify the interface mismatch in control-plane store
echo "=== StoredDaemon interface in control-plane ==="
rg -n -A 20 'export interface StoredDaemon' apps/control-plane/src/store/daemons.ts
echo ""
echo "=== createDaemonStore create method ==="
rg -n -A 25 'create\(request\)' apps/control-plane/src/store/daemons.ts
echo ""
echo "=== Check if workspace exists anywhere in control-plane daemons store ==="
rg -n 'workspace' apps/control-plane/src/store/daemons.tsRepository: arek-e/paws
Length of output: 2553
Control-plane store implementations are missing the workspace field.
The workspace field is correctly added to StoredDaemon and the create() method here (line 50), but the control-plane has a separate StoredDaemon interface and store implementations in apps/control-plane/src/store/daemons.ts that don't include this field.
Update required:
- Add
workspace?: string | undefinedto the StoredDaemon interface (line 12) - Add
workspace: request.workspaceto the in-memory store'screate()method (line 48) - Add
workspaceto the SQLite store's insert statement (line 150-163)
Without these changes, the workspace value will be silently dropped when daemons are created through the control-plane.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/domains/daemon/src/store.ts` at line 13, StoredDaemon in the
control-plane store is missing the workspace field so workspace is dropped;
update the StoredDaemon interface to include workspace?: string | undefined,
modify the in-memory store create() implementation to set workspace:
request.workspace when building the stored object in the create() method, and
update the SQLite store insert statement to include the workspace column and
bind request.workspace in the values for the insert (adjust the INSERT SQL and
parameter list in the SQLite store implementation accordingly).
| .refine((data) => Object.keys(data).length > 0, { | ||
| message: 'At least one field must be provided', | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "types.ts" | grep -E "workspace|domains" | head -20Repository: arek-e/paws
Length of output: 491
🏁 Script executed:
cat -n packages/domains/workspace/src/types.ts | head -100Repository: arek-e/paws
Length of output: 3123
🏁 Script executed:
# Search for tests or usage of UpdateWorkspaceRequestSchema
rg "UpdateWorkspaceRequestSchema" --type ts --type tsx -B 2 -A 5Repository: arek-e/paws
Length of output: 82
🏁 Script executed:
# Look for test files related to workspace types
find . -type f -name "*.test.ts" -o -name "*.spec.ts" | grep -i workspaceRepository: arek-e/paws
Length of output: 101
🏁 Script executed:
rg "UpdateWorkspaceRequestSchema" --type ts -B 2 -A 5Repository: arek-e/paws
Length of output: 4686
🏁 Script executed:
cat -n packages/domains/workspace/src/types.test.tsRepository: arek-e/paws
Length of output: 6565
UpdateWorkspaceRequestSchema accepts payloads with only undefined fields.
The refine check counts object keys only; { name: undefined } passes validation even though no actual update is provided. Fix by checking if at least one value is not undefined:
Fix
- .refine((data) => Object.keys(data).length > 0, {
+ .refine((data) => Object.values(data).some((v) => v !== undefined), {
message: 'At least one field must be provided',
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .refine((data) => Object.keys(data).length > 0, { | |
| message: 'At least one field must be provided', | |
| }); | |
| .refine((data) => Object.values(data).some((v) => v !== undefined), { | |
| message: 'At least one field must be provided', | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/domains/workspace/src/types.ts` around lines 67 - 69, The refine on
UpdateWorkspaceRequestSchema currently only checks Object.keys(data).length,
allowing objects like { name: undefined } to pass; change the predicate used in
the .refine call to verify at least one value is not undefined (e.g., use
Object.values(data).some(value => value !== undefined)) so that payloads with
only undefined fields are rejected and the existing error message remains
accurate.
Proxy (#77): - Add missing audit log fields (statusCode, durationMs, credentialsInjected, protocol) to blocked-request log entry for schema consistency - Add missing statusCode: 502 to upstream-failure log entry - Fix httpsPort log condition: check caCert && caKey, not just caCert Workspace (#82): - Add workspace field to control-plane StoredDaemon interface and both in-memory and SQLite store implementations (was silently dropped) - Add workspace column to daemons DB schema - Fix UpdateWorkspaceRequestSchema refinement: use Object.values().some() instead of Object.keys().length to reject all-undefined payloads - Remove "types": [] from workspace tsconfig.json (violates repo policy) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Proxy (#77): - Add missing audit log fields (statusCode, durationMs, credentialsInjected, protocol) to blocked-request log entry for schema consistency - Add missing statusCode: 502 to upstream-failure log entry - Fix httpsPort log condition: check caCert && caKey, not just caCert Workspace (#82): - Add workspace field to control-plane StoredDaemon interface and both in-memory and SQLite store implementations (was silently dropped) - Add workspace column to daemons DB schema - Fix UpdateWorkspaceRequestSchema refinement: use Object.values().some() instead of Object.keys().length to reject all-undefined payloads - Remove "types": [] from workspace tsconfig.json (violates repo policy) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
@paws/domain-workspacepackage — Workspace entity for grouping repos + daemonsWorkspaceSchema,WorkspaceRepoSchema,WorkspaceSettingsSchemaworkspacefield toDaemonSchemafor linking daemons to workspacesWorkspace schema
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests
Chores