- Add incident reporting routes and logic to handle creation, updating, and retrieval of incidents. - Implement visibility rules for users based on roles (reporters, supervisors). - Create tests for incident reporting functionality to ensure correctness and reliability. - Introduce site and area management routes, including validation for area hierarchy. - Establish user management routes with role-based access control for creating and updating users. - Add setup routes for initializing the application with an organization and admin user. - Implement shared enums and schemas for consistent validation and data handling across the application. - Create a test helper for setting up an in-memory database and API client for testing. - Add TypeScript configuration for server-side code with strict type checking and module resolution.
34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import { zValidator } from '@hono/zod-validator'
|
|
import type { Context, ValidationTargets } from 'hono'
|
|
import { HTTPException } from 'hono/http-exception'
|
|
import type { ZodType } from 'zod'
|
|
import type { SessionUser } from '../auth/sessions.ts'
|
|
import type { Config } from '../config.ts'
|
|
import type { Db } from '../db/client.ts'
|
|
|
|
export interface AppEnv {
|
|
Variables: {
|
|
db: Db
|
|
config: Config
|
|
user: SessionUser | null
|
|
}
|
|
}
|
|
|
|
/** Validates part of the request, answering 400 with field-level issues on failure. */
|
|
export function validate<Target extends keyof ValidationTargets, Schema extends ZodType>(target: Target, schema: Schema) {
|
|
return zValidator(target, schema, (result, c) => {
|
|
if (!result.success) {
|
|
return c.json({ error: 'Invalid request', issues: result.error.issues.map((issue) => ({ path: issue.path.join('.'), message: issue.message })) }, 400)
|
|
}
|
|
})
|
|
}
|
|
|
|
export const fail = (status: 400 | 401 | 403 | 404 | 409 | 429, message: string) => new HTTPException(status, { message })
|
|
|
|
/** The signed-in user; use after `requireAuth`. */
|
|
export function currentUser(c: Context<AppEnv>): SessionUser {
|
|
const user = c.get('user')
|
|
if (!user) throw fail(401, 'Sign in required')
|
|
return user
|
|
}
|