feat: P0 Phase 1 — UI i18n infrastructure & realtime protocol unification#604
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…int 1) - Create ui/i18n.zod.ts with I18nLabelSchema (union: string | i18n object) - Create AriaPropsSchema for WAI-ARIA accessibility attributes - Integrate I18nLabelSchema in view.zod.ts, app.zod.ts, component.zod.ts - Add ARIA props to PageHeaderProps, PageTabsProps, PageCardProps - All 134 existing UI tests + 14 new i18n tests pass Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Create api/realtime-shared.zod.ts with unified PresenceStatus, RealtimeRecordAction, and BasePresenceSchema - Refactor realtime.zod.ts to import from shared module - Refactor websocket.zod.ts to import from shared module - Maintain full backward compatibility (all re-exports preserved) - All 753 API tests + 318 UI tests pass Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds foundational UI i18n schema support (including ARIA-related label capabilities) and unifies duplicated realtime protocol definitions into a shared module to reduce drift across transports.
Changes:
- Introduces
I18nLabelSchema/AriaPropsSchemaand updates UI schemas to accept i18n-aware labels. - Extracts shared realtime enums/schemas into
realtime-shared.zod.ts, withrealtime.zod.tsandwebsocket.zod.tsdelegating to the shared definitions. - Adds new Vitest coverage for the new UI i18n and realtime-shared modules.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/spec/src/ui/view.zod.ts | Updates multiple view label/placeholder/help/empty-state fields to accept I18nLabelSchema. |
| packages/spec/src/ui/index.ts | Exports the new UI i18n schema module. |
| packages/spec/src/ui/i18n.zod.ts | Adds i18n label object/union schemas plus ARIA props schema. |
| packages/spec/src/ui/i18n.test.ts | Adds tests for i18n/ARIA schemas and backward-compatible string labels. |
| packages/spec/src/ui/component.zod.ts | Updates component prop labels to use I18nLabelSchema and adds optional aria props. |
| packages/spec/src/ui/app.zod.ts | Updates app/navigation label/description fields to accept I18nLabelSchema. |
| packages/spec/src/api/websocket.zod.ts | Switches presence status dependency to shared PresenceStatus and keeps websocket presence alias. |
| packages/spec/src/api/realtime.zod.ts | Replaces duplicated enums/schemas with shared exports and deprecates legacy aliases. |
| packages/spec/src/api/realtime-shared.zod.ts | Introduces canonical shared realtime enums and base presence schema. |
| packages/spec/src/api/realtime-shared.test.ts | Adds tests for shared realtime definitions and cross-protocol consistency. |
| packages/spec/src/api/index.ts | Exports the new realtime-shared module from the API barrel. |
| defaultValue: z.string().optional().describe('Fallback value when translation key is not found'), | ||
|
|
||
| /** Interpolation parameters for dynamic translations */ | ||
| params: z.record(z.string(), z.any()).optional().describe('Interpolation parameters (e.g., { count: 5 })'), |
There was a problem hiding this comment.
params is defined as z.any(), which is inconsistent with the rest of the spec (most params/free-form payload maps use z.unknown()), and it weakens downstream JSON Schema/type safety. Consider switching this to z.unknown() (or a tighter schema if intended).
| params: z.record(z.string(), z.any()).optional().describe('Interpolation parameters (e.g., { count: 5 })'), | |
| params: z.record(z.string(), z.unknown()).optional().describe('Interpolation parameters (e.g., { count: 5 })'), |
| * Presence Schema | ||
| * Tracks user online status and metadata | ||
| * Tracks user online status and metadata. | ||
| * Extends the shared BasePresenceSchema for transport-level presence tracking. |
There was a problem hiding this comment.
The JSDoc says RealtimePresenceSchema “extends” BasePresenceSchema, but the code now aliases it directly (export const RealtimePresenceSchema = BasePresenceSchema). Either update the comment to reflect that it’s an alias, or actually extend the base with transport-specific fields if that’s the intent.
| * Extends the shared BasePresenceSchema for transport-level presence tracking. | |
| * Alias of BasePresenceSchema kept for backward compatibility with realtime-specific APIs. |
| import { RealtimePresenceStatus } from './realtime.zod'; | ||
| import { PresenceStatus } from './realtime-shared.zod'; | ||
|
|
||
| // Re-export shared PresenceStatus for backward compatibility |
There was a problem hiding this comment.
The comment says the PresenceStatus re-export is “for backward compatibility”, but websocket.zod.ts previously only exposed WebSocketPresenceStatus (it didn’t export PresenceStatus). Consider clarifying this comment (e.g., “re-export canonical PresenceStatus for convenience/cross-protocol consistency”) to avoid confusion for consumers.
| // Re-export shared PresenceStatus for backward compatibility | |
| // Re-export canonical PresenceStatus for convenience and cross-protocol consistency |
Implements Sprint 1-2 from
PROTOCOL_OPTIMIZATION_REPORT.md: UI internationalization support and realtime protocol deduplication.UI i18n (
ui/i18n.zod.ts)I18nLabelSchema— backward-compatible union: plainstringor{ key, defaultValue?, params? }objectAriaPropsSchema— WAI-ARIA attributes (ariaLabel,ariaDescribedBy,role)view.zod.ts,app.zod.ts,component.zod.ts— alllabelfields now accept both formsRealtime protocol unification (
api/realtime-shared.zod.ts)websocket.zod.tsandrealtime.zod.tshad overlappingPresenceStatusand action enums. Extracted shared definitions intorealtime-shared.zod.ts:PresenceStatus— canonical enum (online | away | busy | offline)RealtimeRecordAction— canonical enum (created | updated | deleted)BasePresenceSchema— shared presence fields (userId,status,lastSeen,metadata)Both files now import from shared and re-export for full backward compatibility. Zero breaking changes.
Test coverage
25 new tests across
i18n.test.tsandrealtime-shared.test.ts. Full suite: 4337 tests pass.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.