Skip to content

Commit a769e38

Browse files
Copilothotlong
andcommitted
fix: align schemas with issue spec — rename TenantUsage fields, make tenantRegion optional, add seedData
- A1: Make tenantRegion optional per issue spec - A2: Rename objectCount→currentObjectCount, totalRecords→currentRecordCount, storageBytes→currentStorageBytes - C2: Add seedData[] to DeployBundleSchema - C3: Add seedData[] to AppManifestSchema - Update all related tests Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 5318d2f commit a769e38

9 files changed

Lines changed: 25 additions & 17 deletions

File tree

packages/spec/src/contracts/deploy-pipeline-service.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe('Deploy Pipeline Service Contract', () => {
1717
views: [],
1818
flows: [],
1919
permissions: [],
20+
seedData: [],
2021
};
2122

2223
const samplePlan: MigrationPlan = {

packages/spec/src/kernel/context.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ describe('TenantRuntimeContextSchema', () => {
217217
expect(() => TenantRuntimeContextSchema.parse({
218218
...baseContext,
219219
tenantPlan: 'free',
220-
tenantRegion: 'us-east',
221220
tenantDbUrl: 'libsql://test.turso.io',
222221
})).toThrow();
223222
});
@@ -227,7 +226,6 @@ describe('TenantRuntimeContextSchema', () => {
227226
...baseContext,
228227
tenantId: '',
229228
tenantPlan: 'free',
230-
tenantRegion: 'us-east',
231229
tenantDbUrl: 'libsql://test.turso.io',
232230
})).toThrow();
233231
});
@@ -237,7 +235,6 @@ describe('TenantRuntimeContextSchema', () => {
237235
...baseContext,
238236
tenantId: 'tenant_test',
239237
tenantPlan: 'basic',
240-
tenantRegion: 'us-east',
241238
tenantDbUrl: 'libsql://test.turso.io',
242239
})).toThrow();
243240
});
@@ -268,9 +265,9 @@ describe('TenantRuntimeContextSchema', () => {
268265
...baseContext,
269266
tenantId: 'tenant_noquota',
270267
tenantPlan: 'free',
271-
tenantRegion: 'us-east',
272268
tenantDbUrl: 'libsql://noquota.turso.io',
273269
});
274270
expect(parsed.tenantQuotas).toBeUndefined();
271+
expect(parsed.tenantRegion).toBeUndefined();
275272
});
276273
});

packages/spec/src/kernel/context.zod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export const TenantRuntimeContextSchema = KernelContextSchema.extend({
153153
tenantPlan: z.enum(['free', 'pro', 'enterprise']).describe('Tenant subscription plan'),
154154

155155
/** Tenant deployment region */
156-
tenantRegion: z.string().min(1).describe('Tenant deployment region'),
156+
tenantRegion: z.string().optional().describe('Tenant deployment region'),
157157

158158
/** Tenant database connection URL */
159159
tenantDbUrl: z.string().min(1).describe('Tenant database connection URL'),

packages/spec/src/system/app-install.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe('AppManifestSchema', () => {
4141
expect(parsed.views).toEqual([]);
4242
expect(parsed.flows).toEqual([]);
4343
expect(parsed.hasSeedData).toBe(false);
44+
expect(parsed.seedData).toEqual([]);
4445
expect(parsed.dependencies).toEqual([]);
4546
});
4647

packages/spec/src/system/app-install.zod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export const AppManifestSchema = z.object({
5252
/** Whether seed data is included */
5353
hasSeedData: z.boolean().default(false).describe('Whether app includes seed data'),
5454

55+
/** Seed data records to populate on install */
56+
seedData: z.array(z.record(z.string(), z.unknown())).default([]).describe('Seed data records'),
57+
5558
/** App dependencies (other apps that must be installed first) */
5659
dependencies: z.array(z.string()).default([]).describe('Required app dependencies'),
5760
}).describe('App manifest for marketplace installation');

packages/spec/src/system/deploy-bundle.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,12 @@ describe('DeployBundleSchema', () => {
178178
views: [{ name: 'task_list', type: 'grid' }],
179179
flows: [],
180180
permissions: [],
181+
seedData: [{ object: 'task', records: [{ name: 'Sample Task' }] }],
181182
};
182183
const parsed = DeployBundleSchema.parse(bundle);
183184
expect(parsed.manifest.version).toBe('1.0.0');
184185
expect(parsed.objects).toHaveLength(1);
186+
expect(parsed.seedData).toHaveLength(1);
185187
});
186188

187189
it('should accept minimal bundle', () => {
@@ -193,6 +195,7 @@ describe('DeployBundleSchema', () => {
193195
expect(parsed.views).toEqual([]);
194196
expect(parsed.flows).toEqual([]);
195197
expect(parsed.permissions).toEqual([]);
198+
expect(parsed.seedData).toEqual([]);
196199
});
197200

198201
it('should reject missing manifest', () => {

packages/spec/src/system/deploy-bundle.zod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ export const DeployBundleSchema = z.object({
219219

220220
/** Permission definitions */
221221
permissions: z.array(z.record(z.string(), z.unknown())).default([]).describe('Permission definitions'),
222+
223+
/** Seed data records to populate after schema migration */
224+
seedData: z.array(z.record(z.string(), z.unknown())).default([]).describe('Seed data records'),
222225
}).describe('Deploy bundle containing all metadata for deployment');
223226

224227
export type DeployBundle = z.infer<typeof DeployBundleSchema>;

packages/spec/src/system/tenant.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -648,34 +648,34 @@ describe('TenantQuotaSchema (extended fields)', () => {
648648
describe('TenantUsageSchema', () => {
649649
it('should accept full usage tracking', () => {
650650
const usage: TenantUsage = {
651-
objectCount: 15,
652-
totalRecords: 50000,
653-
storageBytes: 1073741824,
651+
currentObjectCount: 15,
652+
currentRecordCount: 50000,
653+
currentStorageBytes: 1073741824,
654654
deploymentsToday: 3,
655655
currentUsers: 42,
656656
apiRequestsThisMinute: 120,
657657
lastUpdatedAt: '2026-01-15T10:30:00Z',
658658
};
659659
const parsed = TenantUsageSchema.parse(usage);
660-
expect(parsed.objectCount).toBe(15);
661-
expect(parsed.totalRecords).toBe(50000);
660+
expect(parsed.currentObjectCount).toBe(15);
661+
expect(parsed.currentRecordCount).toBe(50000);
662662
expect(parsed.deploymentsToday).toBe(3);
663663
expect(parsed.currentUsers).toBe(42);
664664
expect(parsed.apiRequestsThisMinute).toBe(120);
665665
});
666666

667667
it('should apply zero defaults', () => {
668668
const parsed = TenantUsageSchema.parse({});
669-
expect(parsed.objectCount).toBe(0);
670-
expect(parsed.totalRecords).toBe(0);
671-
expect(parsed.storageBytes).toBe(0);
669+
expect(parsed.currentObjectCount).toBe(0);
670+
expect(parsed.currentRecordCount).toBe(0);
671+
expect(parsed.currentStorageBytes).toBe(0);
672672
expect(parsed.deploymentsToday).toBe(0);
673673
expect(parsed.currentUsers).toBe(0);
674674
expect(parsed.apiRequestsThisMinute).toBe(0);
675675
});
676676

677677
it('should reject negative values', () => {
678-
expect(() => TenantUsageSchema.parse({ objectCount: -1 })).toThrow();
678+
expect(() => TenantUsageSchema.parse({ currentObjectCount: -1 })).toThrow();
679679
expect(() => TenantUsageSchema.parse({ currentUsers: -1 })).toThrow();
680680
expect(() => TenantUsageSchema.parse({ apiRequestsThisMinute: -1 })).toThrow();
681681
});

packages/spec/src/system/tenant.zod.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ export type TenantQuota = z.infer<typeof TenantQuotaSchema>;
103103
*/
104104
export const TenantUsageSchema = z.object({
105105
/** Current number of custom objects */
106-
objectCount: z.number().int().min(0).default(0).describe('Current number of custom objects'),
106+
currentObjectCount: z.number().int().min(0).default(0).describe('Current number of custom objects'),
107107
/** Current total record count across all objects */
108-
totalRecords: z.number().int().min(0).default(0).describe('Total records across all objects'),
108+
currentRecordCount: z.number().int().min(0).default(0).describe('Total records across all objects'),
109109
/** Current storage usage in bytes */
110-
storageBytes: z.number().int().min(0).default(0).describe('Current storage usage in bytes'),
110+
currentStorageBytes: z.number().int().min(0).default(0).describe('Current storage usage in bytes'),
111111
/** Deployments executed today */
112112
deploymentsToday: z.number().int().min(0).default(0).describe('Deployments executed today'),
113113
/** Current number of active users */

0 commit comments

Comments
 (0)