Files
NetForge/src/app/api/accounting/periods/route.ts
kevin-asprec a53ee9cd1c feat(02-01): COA auto-provisioning on tenant signup + API routes + tests
- Create seed-coa.ts: seedChartOfAccounts(tx, tenantId) seeds 28 accounts in transaction
- Update tenant.ts: createTenant() calls seedChartOfAccounts inside $transaction block
- Add GET /api/accounting/accounts — list COA for tenant (requires read:Account)
- Add GET /api/accounting/periods — list accounting periods (requires read:Account)
- Add POST /api/accounting/periods/[id]/close — close period (requires manage:Account)
- Add 28 integration tests: COA definition, seeding, period management, createTenant integration
- All 121 tests pass (93 existing + 28 new)
2026-03-04 22:51:52 +08:00

45 lines
1.3 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { withPermission } from "@/lib/middleware/authorize";
import { withTenantContext } from "@/lib/prisma-tenant";
/**
* GET /api/accounting/periods
*
* Lists all accounting periods for the authenticated tenant.
* Ordered by year descending, then month descending (most recent first).
*
* Requires: ADMIN role (read on Account subject).
*
* Response:
* 200 OK — Array of { id, year, month, status, closedAt, closedById, createdAt }
* 401 Unauthorized — no session
* 403 Forbidden — insufficient role
*/
export const GET = withPermission("read", "Account")(
async (_req: NextRequest, { user }) => {
if (!user.tenantId) {
return NextResponse.json(
{ error: "No tenant context — super-admins must use the admin API" },
{ status: 400 }
);
}
const tenantPrisma = withTenantContext(user.tenantId);
const periods = await tenantPrisma.accountingPeriod.findMany({
orderBy: [{ year: "desc" }, { month: "desc" }],
select: {
id: true,
year: true,
month: true,
status: true,
closedAt: true,
closedById: true,
createdAt: true,
},
});
return NextResponse.json(periods);
}
);