TypeScript/Bun project scaffold
- Stack: Bun, Hono, Drizzle ORM, Zod, Handlebars, Pino - Models: ticket, queue, transaction, scrip, template, custom_field, user, lifecycle - Scrip engine: prepare/commit two-phase dispatch, template rendering, mock actions - Lifecycle validator: state machine transition validation with wildcard support - Routes: health, tickets (full CRUD + preview + transactions), queues, scrips, custom-fields, lifecycles - Middleware: Pino logging, error handler - Database: Drizzle ORM schema + initial migration (10 tables) - Type-check: passes (tsc --noEmit, zero errors)
This commit is contained in:
13
src/models/custom-field.ts
Normal file
13
src/models/custom-field.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { customFields } from '../db/schema.ts';
|
||||
|
||||
export type CustomField = InferSelectModel<typeof customFields>;
|
||||
|
||||
export const CustomFieldType = {
|
||||
SelectOne: 'SelectOne',
|
||||
SelectMultiple: 'SelectMultiple',
|
||||
Text: 'Text',
|
||||
Date: 'Date',
|
||||
} as const;
|
||||
|
||||
export type CustomFieldType = (typeof CustomFieldType)[keyof typeof CustomFieldType];
|
||||
4
src/models/lifecycle.ts
Normal file
4
src/models/lifecycle.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { lifecycles } from '../db/schema.ts';
|
||||
|
||||
export type Lifecycle = InferSelectModel<typeof lifecycles>;
|
||||
11
src/models/queue.ts
Normal file
11
src/models/queue.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { z } from 'zod/v4';
|
||||
import { queues } from '../db/schema.ts';
|
||||
|
||||
export type Queue = InferSelectModel<typeof queues>;
|
||||
|
||||
export const CreateQueueSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
lifecycle_id: z.string().uuid().optional(),
|
||||
});
|
||||
26
src/models/scrip.ts
Normal file
26
src/models/scrip.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { z } from 'zod/v4';
|
||||
import { scrips } from '../db/schema.ts';
|
||||
|
||||
export type Scrip = InferSelectModel<typeof scrips>;
|
||||
|
||||
export const ScripStage = {
|
||||
TransactionCreate: 'TransactionCreate',
|
||||
TransactionBatch: 'TransactionBatch',
|
||||
} as const;
|
||||
|
||||
export type ScripStage = (typeof ScripStage)[keyof typeof ScripStage];
|
||||
|
||||
export const CreateScripSchema = z.object({
|
||||
queue_id: z.string().uuid().nullable().optional(),
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
condition_type: z.string().min(1),
|
||||
condition_config: z.record(z.string(), z.unknown()).default({}),
|
||||
action_type: z.string().min(1),
|
||||
action_config: z.record(z.string(), z.unknown()).default({}),
|
||||
template_id: z.string().uuid().optional(),
|
||||
stage: z.enum(['TransactionCreate', 'TransactionBatch']).default('TransactionCreate'),
|
||||
sort_order: z.number().int().default(0),
|
||||
disabled: z.boolean().default(false),
|
||||
});
|
||||
16
src/models/ticket.ts
Normal file
16
src/models/ticket.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { z } from 'zod/v4';
|
||||
import { tickets } from '../db/schema.ts';
|
||||
|
||||
export type Ticket = InferSelectModel<typeof tickets>;
|
||||
|
||||
export const CreateTicketSchema = z.object({
|
||||
subject: z.string().min(1),
|
||||
queue_id: z.string().uuid(),
|
||||
});
|
||||
|
||||
export const UpdateTicketSchema = z.object({
|
||||
subject: z.string().min(1).optional(),
|
||||
status: z.string().min(1).optional(),
|
||||
owner_id: z.string().uuid().optional(),
|
||||
});
|
||||
16
src/models/transaction.ts
Normal file
16
src/models/transaction.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { transactions } from '../db/schema.ts';
|
||||
|
||||
export type Transaction = InferSelectModel<typeof transactions>;
|
||||
|
||||
export const TransactionType = {
|
||||
Create: 'Create',
|
||||
StatusChange: 'StatusChange',
|
||||
SetOwner: 'SetOwner',
|
||||
AddWatcher: 'AddWatcher',
|
||||
Comment: 'Comment',
|
||||
CustomField: 'CustomField',
|
||||
Correspond: 'Correspond',
|
||||
} as const;
|
||||
|
||||
export type TransactionType = (typeof TransactionType)[keyof typeof TransactionType];
|
||||
4
src/models/user.ts
Normal file
4
src/models/user.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { InferSelectModel } from 'drizzle-orm';
|
||||
import { users } from '../db/schema.ts';
|
||||
|
||||
export type User = InferSelectModel<typeof users>;
|
||||
Reference in New Issue
Block a user