diff --git a/packages/api/src/routers/_app.ts b/packages/api/src/routers/_app.ts index 5626270..8f03af3 100644 --- a/packages/api/src/routers/_app.ts +++ b/packages/api/src/routers/_app.ts @@ -1,8 +1,12 @@ import { router } from '../trpc'; import { pingRouter } from './ping'; +import { workstationRouter } from './workstation'; +import { userRouter } from './user'; export const appRouter = router({ ping: pingRouter, + workstation: workstationRouter, + user: userRouter, }); export type AppRouter = typeof appRouter; diff --git a/packages/api/src/routers/user.ts b/packages/api/src/routers/user.ts new file mode 100644 index 0000000..a344268 --- /dev/null +++ b/packages/api/src/routers/user.ts @@ -0,0 +1,11 @@ +import { protectedProcedure, router } from '../trpc'; + +export const userRouter = router({ + listOperators: protectedProcedure.query(({ ctx }) => { + return ctx.db.user.findMany({ + where: { role: 'OPERATOR' }, + select: { id: true, email: true }, + orderBy: { email: 'asc' }, + }); + }), +}); diff --git a/packages/api/src/routers/workstation.ts b/packages/api/src/routers/workstation.ts new file mode 100644 index 0000000..433ee74 --- /dev/null +++ b/packages/api/src/routers/workstation.ts @@ -0,0 +1,9 @@ +import { protectedProcedure, router } from '../trpc'; + +export const workstationRouter = router({ + list: protectedProcedure.query(({ ctx }) => { + return ctx.db.workstation.findMany({ + orderBy: [{ area: 'asc' }, { code: 'asc' }], + }); + }), +}); diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts index 47b84b0..c79b180 100644 --- a/packages/db/src/index.ts +++ b/packages/db/src/index.ts @@ -1,4 +1,4 @@ export { prisma, type DbClient } from './client'; export { tenantScoped, type TenantScopedClient } from './tenant-extension'; -export { Prisma, UserRole } from '@prisma/client'; -export type { User, Tenant, Workstation, DomainEvent } from '@prisma/client'; +export { Prisma, UserRole, MaintenanceRequestStatus } from '@prisma/client'; +export type { User, Tenant, Workstation, DomainEvent, MaintenanceRequest } from '@prisma/client'; diff --git a/scripts/routers-smoke.ts b/scripts/routers-smoke.ts new file mode 100644 index 0000000..8452f90 --- /dev/null +++ b/scripts/routers-smoke.ts @@ -0,0 +1,59 @@ +/** + * AC verification for Passo 5: + * workstation.list and user.listOperators return seeds from Passo 2. + */ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { config as loadEnv } from 'dotenv'; + +const here = path.dirname(fileURLToPath(import.meta.url)); +loadEnv({ path: path.resolve(here, '../.env') }); + +import { prisma, tenantScoped } from '../packages/db/src/index.js'; +import { appRouter, createTRPCContext } from '../packages/api/src/index.js'; +import { createCallerFactory } from '../packages/api/src/trpc.js'; + +async function main() { + // Resolve the demo tenant and admin user from the real DB + const adminUser = await prisma.user.findFirst({ where: { email: 'admin@demo.local' } }); + if (!adminUser) throw new Error('Run pnpm db:seed first'); + + const ctx = await createTRPCContext({ + user: { + id: adminUser.id, + email: adminUser.email, + role: adminUser.role as 'ADMIN', + tenantId: adminUser.tenantId, + }, + headers: new Headers(), + }); + + const caller = createCallerFactory(appRouter)(ctx); + + // workstation.list + const workstations = await caller.workstation.list(); + const wsCodes = workstations.map((w) => w.code).sort(); + const expectedCodes = ['CTR04', 'MTG_01', 'QVN_RTL_2']; + if (JSON.stringify(wsCodes) !== JSON.stringify(expectedCodes)) { + throw new Error(`workstation.list mismatch: got ${JSON.stringify(wsCodes)}`); + } + console.log(`workstation.list → ${wsCodes.join(', ')} ✓`); + + // user.listOperators + const operators = await caller.user.listOperators(); + const opEmails = operators.map((u) => u.email).sort(); + const expectedEmails = ['op1@demo.local', 'op2@demo.local', 'op3@demo.local']; + if (JSON.stringify(opEmails) !== JSON.stringify(expectedEmails)) { + throw new Error(`user.listOperators mismatch: got ${JSON.stringify(opEmails)}`); + } + console.log(`user.listOperators → ${opEmails.join(', ')} ✓`); + + await prisma.$disconnect(); + console.log('\nRouter AC PASSED'); +} + +main().catch(async (err) => { + console.error('Router AC FAILED:', err); + await prisma.$disconnect(); + process.exit(1); +});