Initial commit
This commit is contained in:
23
packages/schemas/package.json
Normal file
23
packages/schemas/package.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "@dwellops/schemas",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./src/index.ts"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"@dwellops/config": "workspace:*"
|
||||
}
|
||||
}
|
||||
29
packages/schemas/src/auth.ts
Normal file
29
packages/schemas/src/auth.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { z } from 'zod';
|
||||
import { nonEmptyString } from './common';
|
||||
|
||||
/** Magic link request schema. */
|
||||
export const magicLinkRequestSchema = z.object({
|
||||
email: z.string().email().toLowerCase(),
|
||||
redirectTo: z.string().url().optional(),
|
||||
});
|
||||
|
||||
export type MagicLinkRequestInput = z.infer<typeof magicLinkRequestSchema>;
|
||||
|
||||
/** Passkey registration options request. */
|
||||
export const passkeyRegisterRequestSchema = z.object({
|
||||
userId: nonEmptyString,
|
||||
});
|
||||
|
||||
export type PasskeyRegisterRequestInput = z.infer<typeof passkeyRegisterRequestSchema>;
|
||||
|
||||
/** HOA role enum for validation. */
|
||||
export const hoaRoleSchema = z.enum([
|
||||
'ADMIN',
|
||||
'BOARD_MEMBER',
|
||||
'TREASURER',
|
||||
'OWNER',
|
||||
'TENANT',
|
||||
'VIEWER',
|
||||
]);
|
||||
|
||||
export type HoaRoleInput = z.infer<typeof hoaRoleSchema>;
|
||||
18
packages/schemas/src/common.ts
Normal file
18
packages/schemas/src/common.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
/** Shared pagination query parameter schema. */
|
||||
export const paginationSchema = z.object({
|
||||
page: z.coerce.number().int().min(1).default(1),
|
||||
pageSize: z.coerce.number().int().min(1).max(100).default(20),
|
||||
});
|
||||
|
||||
export type PaginationInput = z.infer<typeof paginationSchema>;
|
||||
|
||||
/** Non-empty trimmed string helper. */
|
||||
export const nonEmptyString = z.string().trim().min(1);
|
||||
|
||||
/** Cuid2-style ID string. */
|
||||
export const idSchema = z.string().cuid2();
|
||||
|
||||
/** ISO date string. */
|
||||
export const isoDateString = z.string().datetime();
|
||||
46
packages/schemas/src/hoa.ts
Normal file
46
packages/schemas/src/hoa.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { z } from 'zod';
|
||||
import { nonEmptyString, paginationSchema } from './common';
|
||||
import { hoaRoleSchema } from './auth';
|
||||
|
||||
/** Schema for creating an HOA. */
|
||||
export const createHoaSchema = z.object({
|
||||
name: nonEmptyString.max(255),
|
||||
slug: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(100)
|
||||
.regex(/^[a-z0-9-]+$/, 'Slug must be lowercase alphanumeric with hyphens'),
|
||||
description: z.string().trim().max(1000).optional(),
|
||||
});
|
||||
|
||||
export type CreateHoaInput = z.infer<typeof createHoaSchema>;
|
||||
|
||||
/** Schema for updating an HOA. */
|
||||
export const updateHoaSchema = createHoaSchema.partial();
|
||||
export type UpdateHoaInput = z.infer<typeof updateHoaSchema>;
|
||||
|
||||
/** Schema for creating a unit within an HOA. */
|
||||
export const createUnitSchema = z.object({
|
||||
identifier: nonEmptyString.max(100),
|
||||
address: z.string().trim().max(500).optional(),
|
||||
});
|
||||
|
||||
export type CreateUnitInput = z.infer<typeof createUnitSchema>;
|
||||
|
||||
/** Schema for creating a membership. */
|
||||
export const createMembershipSchema = z.object({
|
||||
userId: nonEmptyString,
|
||||
hoaId: nonEmptyString,
|
||||
unitId: z.string().optional(),
|
||||
role: hoaRoleSchema,
|
||||
});
|
||||
|
||||
export type CreateMembershipInput = z.infer<typeof createMembershipSchema>;
|
||||
|
||||
/** HOA list query schema. */
|
||||
export const listHoasSchema = paginationSchema.extend({
|
||||
search: z.string().trim().optional(),
|
||||
});
|
||||
|
||||
export type ListHoasInput = z.infer<typeof listHoasSchema>;
|
||||
3
packages/schemas/src/index.ts
Normal file
3
packages/schemas/src/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './common';
|
||||
export * from './auth';
|
||||
export * from './hoa';
|
||||
9
packages/schemas/tsconfig.json
Normal file
9
packages/schemas/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "@dwellops/config/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
1
packages/schemas/tsconfig.tsbuildinfo
Normal file
1
packages/schemas/tsconfig.tsbuildinfo
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user