chore: full technical rename planarchy → capakraken

Complete rename of all technical identifiers across the codebase:

Package names (11 packages):
- @planarchy/* → @capakraken/* in all package.json, tsconfig, imports

Import statements: 277 files, 548 occurrences replaced

Database & Docker:
- PostgreSQL user/db: planarchy → capakraken
- Docker volumes: planarchy_pgdata → capakraken_pgdata
- Connection strings updated in docker-compose, .env, CI

CI/CD:
- GitHub Actions workflow: all filter commands updated
- Test database credentials updated

Infrastructure:
- Redis channel: planarchy:sse → capakraken:sse
- Logger service name: planarchy-api → capakraken-api
- Anonymization seed updated
- Start/stop/restart scripts updated

Test data:
- Seed emails: @planarchy.dev → @capakraken.dev
- E2E test credentials: all 11 spec files updated
- Email defaults: @planarchy.app → @capakraken.app
- localStorage keys: planarchy_* → capakraken_*

Documentation: 30+ .md files updated

Verification:
- pnpm install: workspace resolution works
- TypeScript: only pre-existing TS2589 (no new errors)
- Engine: 310/310 tests pass
- Staffing: 37/37 tests pass

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-03-27 13:18:09 +01:00
parent f46b38f457
commit cd78f72f33
303 changed files with 938 additions and 878 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
{
"name": "@planarchy/api",
"name": "@capakraken/api",
"version": "0.1.0",
"private": true,
"type": "module",
@@ -17,11 +17,11 @@
},
"dependencies": {
"@node-rs/argon2": "^2.0.2",
"@planarchy/application": "workspace:*",
"@planarchy/db": "workspace:*",
"@planarchy/engine": "workspace:*",
"@planarchy/shared": "workspace:*",
"@planarchy/staffing": "workspace:*",
"@capakraken/application": "workspace:*",
"@capakraken/db": "workspace:*",
"@capakraken/engine": "workspace:*",
"@capakraken/shared": "workspace:*",
"@capakraken/staffing": "workspace:*",
"@trpc/server": "^11.0.0",
"@types/nodemailer": "^7.0.11",
"ioredis": "^5.10.0",
@@ -31,7 +31,7 @@
"zod": "^3.23.8"
},
"devDependencies": {
"@planarchy/tsconfig": "workspace:*",
"@capakraken/tsconfig": "workspace:*",
"@types/node": "^22.10.2",
"typescript": "^5.6.3",
"vitest": "^2.1.8"
@@ -1,4 +1,4 @@
import { AllocationStatus, SystemRole } from "@planarchy/shared";
import { AllocationStatus, SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { allocationRouter } from "../router/allocation.js";
import { emitAllocationCreated, emitAllocationDeleted } from "../sse/event-bus.js";
@@ -1,4 +1,4 @@
import { BlueprintTarget, FieldType, type BlueprintFieldDefinition } from "@planarchy/shared";
import { BlueprintTarget, FieldType, type BlueprintFieldDefinition } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { describe, expect, it, vi } from "vitest";
import { assertBlueprintDynamicFields } from "../router/blueprint-validation.js";
@@ -1,8 +1,8 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@planarchy/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@planarchy/application")>();
vi.mock("@capakraken/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@capakraken/application")>();
return {
...actual,
isChargeabilityActualBooking: actual.isChargeabilityActualBooking,
@@ -10,7 +10,7 @@ vi.mock("@planarchy/application", async (importOriginal) => {
};
});
import { listAssignmentBookings } from "@planarchy/application";
import { listAssignmentBookings } from "@capakraken/application";
import { chargeabilityReportRouter } from "../router/chargeability-report.js";
import { createCallerFactory } from "../trpc.js";
@@ -1,4 +1,4 @@
import { FieldType } from "@planarchy/shared";
import { FieldType } from "@capakraken/shared";
import { describe, expect, it } from "vitest";
import { buildDynamicFieldWhereClauses } from "../router/custom-field-filters.js";
@@ -1,8 +1,8 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@planarchy/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@planarchy/application")>();
vi.mock("@capakraken/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@capakraken/application")>();
return {
...actual,
getDashboardOverview: vi.fn(),
@@ -29,7 +29,7 @@ import {
getDashboardDemand,
getDashboardTopValueResources,
getDashboardChargeabilityOverview,
} from "@planarchy/application";
} from "@capakraken/application";
import { dashboardRouter } from "../router/dashboard.js";
import { createCallerFactory } from "../trpc.js";
@@ -1,10 +1,10 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { effortRuleRouter } from "../router/effort-rule.js";
import { createCallerFactory } from "../trpc.js";
// Mock the engine — we focus on the router/DB layer, not the pure engine logic
vi.mock("@planarchy/engine", () => ({
vi.mock("@capakraken/engine", () => ({
expandScopeToEffort: vi.fn().mockReturnValue({
lines: [
{
@@ -1,10 +1,10 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { entitlementRouter } from "../router/entitlement.js";
import { createCallerFactory } from "../trpc.js";
// Mock @planarchy/db to provide the enums used in the router
vi.mock("@planarchy/db", () => ({
// Mock @capakraken/db to provide the enums used in the router
vi.mock("@capakraken/db", () => ({
VacationType: { ANNUAL: "ANNUAL", SICK: "SICK", OTHER: "OTHER", PUBLIC_HOLIDAY: "PUBLIC_HOLIDAY" },
VacationStatus: { APPROVED: "APPROVED", PENDING: "PENDING", REJECTED: "REJECTED" },
}));
@@ -3,7 +3,7 @@ import {
EstimateStatus,
EstimateVersionStatus,
SystemRole,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { describe, expect, it, vi } from "vitest";
import { estimateRouter } from "../router/estimate.js";
@@ -302,7 +302,7 @@ describe("estimate router", () => {
const updated = { ...baseEstimate, name: "Updated Name" };
const auditLogCreate = vi.fn().mockResolvedValue({});
// The router delegates to @planarchy/application updateEstimateDraft.
// The router delegates to @capakraken/application updateEstimateDraft.
// The application function calls db.estimate.findUnique and then
// db.estimateVersion.update (among others). We mock the DB calls
// that the application layer uses under the hood.
@@ -1,4 +1,4 @@
import { SSE_EVENT_TYPES } from "@planarchy/shared";
import { SSE_EVENT_TYPES } from "@capakraken/shared";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
cancelPendingEvents,
@@ -1,10 +1,10 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { experienceMultiplierRouter } from "../router/experience-multiplier.js";
import { createCallerFactory } from "../trpc.js";
// Mock the engine — we focus on the router/DB layer, not the pure engine logic
vi.mock("@planarchy/engine", () => ({
vi.mock("@capakraken/engine", () => ({
applyExperienceMultipliers: vi.fn().mockReturnValue({
adjustedCostRateCents: 12000,
adjustedBillRateCents: 18000,
@@ -413,7 +413,7 @@ describe("experienceMultiplier.preview", () => {
it("reports no changes when rates are unchanged", async () => {
// Import the mock to override for this test
const { applyExperienceMultipliers } = await import("@planarchy/engine");
const { applyExperienceMultipliers } = await import("@capakraken/engine");
const mockFn = applyExperienceMultipliers as ReturnType<typeof vi.fn>;
mockFn.mockReturnValueOnce({
adjustedCostRateCents: 10000,
@@ -505,7 +505,7 @@ describe("experienceMultiplier.applyRules", () => {
});
it("skips unchanged lines (no update call)", async () => {
const { applyExperienceMultipliersBatch } = await import("@planarchy/engine");
const { applyExperienceMultipliersBatch } = await import("@capakraken/engine");
const mockFn = applyExperienceMultipliersBatch as ReturnType<typeof vi.fn>;
mockFn.mockReturnValueOnce({
results: [
@@ -1,4 +1,4 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { notificationRouter } from "../router/notification.js";
import { createCallerFactory } from "../trpc.js";
@@ -1,4 +1,4 @@
import { AllocationStatus } from "@planarchy/shared";
import { AllocationStatus } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { loadProjectPlanningReadModel } from "../router/project-planning-read-model.js";
@@ -1,4 +1,4 @@
import { AllocationStatus } from "@planarchy/shared";
import { AllocationStatus } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { projectRouter } from "../router/project.js";
import { createCallerFactory } from "../trpc.js";
@@ -1,10 +1,10 @@
import { OrderType, AllocationType, ProjectStatus, SystemRole } from "@planarchy/shared";
import { OrderType, AllocationType, ProjectStatus, SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { projectRouter } from "../router/project.js";
import { createCallerFactory } from "../trpc.js";
vi.mock("@planarchy/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@planarchy/application")>();
vi.mock("@capakraken/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@capakraken/application")>();
return {
...actual,
countPlanningEntries: vi.fn().mockResolvedValue({ countsByProjectId: new Map() }),
@@ -433,7 +433,7 @@ describe("project router", () => {
},
};
const { listAssignmentBookings } = await import("@planarchy/application");
const { listAssignmentBookings } = await import("@capakraken/application");
vi.mocked(listAssignmentBookings).mockResolvedValue([]);
const caller = createControllerCaller(db);
@@ -452,7 +452,7 @@ describe("project router", () => {
},
};
const { listAssignmentBookings } = await import("@planarchy/application");
const { listAssignmentBookings } = await import("@capakraken/application");
vi.mocked(listAssignmentBookings).mockResolvedValue([
{
id: "a1",
@@ -1,8 +1,8 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@planarchy/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@planarchy/application")>();
vi.mock("@capakraken/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@capakraken/application")>();
return {
...actual,
isChargeabilityActualBooking: actual.isChargeabilityActualBooking,
@@ -1,9 +1,9 @@
import { SystemRole } from "@planarchy/shared";
import { ResourceType } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { ResourceType } from "@capakraken/shared";
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@planarchy/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@planarchy/application")>();
vi.mock("@capakraken/application", async (importOriginal) => {
const actual = await importOriginal<typeof import("@capakraken/application")>();
return {
...actual,
isChargeabilityActualBooking: actual.isChargeabilityActualBooking,
@@ -13,7 +13,7 @@ vi.mock("@planarchy/application", async (importOriginal) => {
};
});
import { listAssignmentBookings } from "@planarchy/application";
import { listAssignmentBookings } from "@capakraken/application";
import { resourceRouter } from "../router/resource.js";
import { createCallerFactory } from "../trpc.js";
@@ -1,4 +1,4 @@
import { AllocationStatus, SystemRole } from "@planarchy/shared";
import { AllocationStatus, SystemRole } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { describe, expect, it, vi } from "vitest";
import { roleRouter } from "../router/role.js";
@@ -1,10 +1,10 @@
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { staffingRouter } from "../router/staffing.js";
import { createCallerFactory } from "../trpc.js";
// Mock the pure-logic packages — we focus on the router/DB layer
vi.mock("@planarchy/staffing", () => ({
vi.mock("@capakraken/staffing", () => ({
rankResources: vi.fn().mockImplementation((input: { resources: { id: string }[] }) =>
input.resources.map((r: { id: string }, i: number) => ({
resourceId: r.id,
@@ -36,7 +36,7 @@ vi.mock("@planarchy/staffing", () => ({
]),
}));
vi.mock("@planarchy/application", () => ({
vi.mock("@capakraken/application", () => ({
listAssignmentBookings: vi.fn().mockResolvedValue([]),
}));
@@ -159,7 +159,7 @@ describe("staffing.getSuggestions", () => {
},
};
const { rankResources } = await import("@planarchy/staffing");
const { rankResources } = await import("@capakraken/staffing");
const caller = createProtectedCaller(db);
await caller.getSuggestions({
requiredSkills: ["Compositing"],
@@ -277,7 +277,7 @@ describe("staffing.findCapacity", () => {
},
};
const { findCapacityWindows } = await import("@planarchy/staffing");
const { findCapacityWindows } = await import("@capakraken/staffing");
const caller = createProtectedCaller(db);
await caller.findCapacity({
resourceId: "res_1",
@@ -1,4 +1,4 @@
import { AllocationStatus, SystemRole } from "@planarchy/shared";
import { AllocationStatus, SystemRole } from "@capakraken/shared";
import { describe, expect, it, vi } from "vitest";
import { timelineRouter } from "../router/timeline.js";
import { createCallerFactory } from "../trpc.js";
@@ -1,4 +1,4 @@
import { AllocationStatus } from "@planarchy/shared";
import { AllocationStatus } from "@capakraken/shared";
import { describe, expect, it } from "vitest";
import { buildTimelineShiftPlan } from "../router/timeline-shift-planning.js";
@@ -1,5 +1,5 @@
import { SystemRole } from "@planarchy/shared";
import { VacationStatus, VacationType } from "@planarchy/db";
import { SystemRole } from "@capakraken/shared";
import { VacationStatus, VacationType } from "@capakraken/db";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { vacationRouter } from "../router/vacation.js";
import { createCallerFactory } from "../trpc.js";
+2 -2
View File
@@ -1,8 +1,8 @@
import { createHash } from "node:crypto";
import type { PrismaClient } from "@planarchy/db";
import type { PrismaClient } from "@capakraken/db";
const DEFAULT_ANONYMIZATION_DOMAIN = "superhartmut.de";
const DEFAULT_ANONYMIZATION_SEED = "planarchy-superhartmut-global";
const DEFAULT_ANONYMIZATION_SEED = "capakraken-superhartmut-global";
type AliasEntry = {
name: string;
+1 -1
View File
@@ -1,4 +1,4 @@
import type { PrismaClient, Prisma } from "@planarchy/db";
import type { PrismaClient, Prisma } from "@capakraken/db";
import { logger } from "./logger.js";
type AuditAction = "CREATE" | "UPDATE" | "DELETE" | "SHIFT" | "IMPORT";
+3 -3
View File
@@ -1,6 +1,6 @@
import { listAssignmentBookings } from "@planarchy/application";
import { rankResources } from "@planarchy/staffing";
import type { SkillEntry } from "@planarchy/shared";
import { listAssignmentBookings } from "@capakraken/application";
import { rankResources } from "@capakraken/staffing";
import type { SkillEntry } from "@capakraken/shared";
import { createNotificationsForUsers } from "./create-notification.js";
/**
+1 -1
View File
@@ -1,4 +1,4 @@
import { listAssignmentBookings } from "@planarchy/application";
import { listAssignmentBookings } from "@capakraken/application";
import { createNotificationsForUsers } from "./create-notification.js";
type DbClient = Parameters<typeof listAssignmentBookings>[0] & {
+4 -4
View File
@@ -4,10 +4,10 @@ import {
countWorkingDaysInOverlap,
calculateSAH,
type AssignmentSlice,
} from "@planarchy/engine";
import type { SpainScheduleRule } from "@planarchy/shared";
import { isChargeabilityActualBooking, listAssignmentBookings } from "@planarchy/application";
import { VacationStatus } from "@planarchy/db";
} from "@capakraken/engine";
import type { SpainScheduleRule } from "@capakraken/shared";
import { isChargeabilityActualBooking, listAssignmentBookings } from "@capakraken/application";
import { VacationStatus } from "@capakraken/db";
import { createNotificationsForUsers } from "./create-notification.js";
/**
+2 -2
View File
@@ -3,7 +3,7 @@
* Non-blocking — errors are logged, not thrown.
*/
import nodemailer from "nodemailer";
import { prisma as db } from "@planarchy/db";
import { prisma as db } from "@capakraken/db";
interface EmailPayload {
to: string | string[];
@@ -23,7 +23,7 @@ async function getSmtpConfig() {
settings.smtpUser && settings.smtpPassword
? { user: settings.smtpUser, pass: settings.smtpPassword }
: undefined,
from: settings.smtpFrom ?? settings.smtpUser ?? "noreply@planarchy.app",
from: settings.smtpFrom ?? settings.smtpUser ?? "noreply@capakraken.app",
};
}
+1 -1
View File
@@ -9,7 +9,7 @@
* Duplicate-safe: skips holidays that already exist (by date + type + resourceId).
*/
import { getPublicHolidays } from "@planarchy/shared";
import { getPublicHolidays } from "@capakraken/shared";
interface MinimalVacation {
resourceId: string;
+1 -1
View File
@@ -6,7 +6,7 @@ const LOG_LEVEL = process.env["LOG_LEVEL"] ?? "info";
export const logger = pino({
level: LOG_LEVEL,
base: { service: "planarchy-api" },
base: { service: "capakraken-api" },
...(isProduction
? {}
: {
@@ -1,4 +1,4 @@
import { prisma } from "@planarchy/db";
import { prisma } from "@capakraken/db";
type PrismaClient = typeof prisma;
+1 -1
View File
@@ -1,4 +1,4 @@
import { prisma } from "@planarchy/db";
import { prisma } from "@capakraken/db";
import { emitReminderDue, emitNotificationCreated } from "../sse/event-bus.js";
const POLL_INTERVAL_MS = 60_000; // 60 seconds
+1 -1
View File
@@ -1,4 +1,4 @@
import { prisma } from "@planarchy/db";
import { prisma } from "@capakraken/db";
type PrismaClient = typeof prisma;
+1 -1
View File
@@ -1,4 +1,4 @@
import { VacationStatus } from "@planarchy/db";
import { VacationStatus } from "@capakraken/db";
import { createNotification } from "./create-notification.js";
type DbClient = {
+10 -10
View File
@@ -11,7 +11,7 @@ import {
updateAllocationEntry,
updateAssignment,
updateDemandRequirement,
} from "@planarchy/application";
} from "@capakraken/application";
import {
AllocationStatus,
buildTaskAction,
@@ -24,7 +24,7 @@ import {
UpdateAssignmentSchema,
UpdateAllocationSchema,
UpdateDemandRequirementSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -109,7 +109,7 @@ function toAssignmentUpdateInput(input: AllocationEntryUpdateInput) {
}
async function loadAllocationReadModel(
db: Pick<import("@planarchy/db").PrismaClient, "demandRequirement" | "assignment" | "systemSettings" | "resource">,
db: Pick<import("@capakraken/db").PrismaClient, "demandRequirement" | "assignment" | "systemSettings" | "resource">,
input: AllocationListFilters,
) {
const [demandRequirements, assignments] = await Promise.all([
@@ -136,7 +136,7 @@ async function loadAllocationReadModel(
const readModel = buildSplitAllocationReadModel({ demandRequirements, assignments });
const directory = await getAnonymizationDirectory(db as import("@planarchy/db").PrismaClient);
const directory = await getAnonymizationDirectory(db as import("@capakraken/db").PrismaClient);
if (!directory) return readModel;
function anonymizeAllocation<T extends { resource?: { id: string; eid?: string | null; displayName?: string | null; email?: string | null } | null }>(alloc: T): T {
@@ -153,7 +153,7 @@ async function loadAllocationReadModel(
}
async function findAllocationEntryOrNull(
db: Pick<import("@planarchy/db").PrismaClient, "demandRequirement" | "assignment">,
db: Pick<import("@capakraken/db").PrismaClient, "demandRequirement" | "assignment">,
id: string,
) {
try {
@@ -611,7 +611,7 @@ export const allocationRouter = createTRPCRouter({
entityType: "DemandRequirement",
entityId: input.id,
action: "DELETE",
changes: { before: existing } as unknown as import("@planarchy/db").Prisma.InputJsonValue,
changes: { before: existing } as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
});
@@ -705,7 +705,7 @@ export const allocationRouter = createTRPCRouter({
changes: {
before: existing.entry,
after: updatedAllocation,
} as unknown as import("@planarchy/db").Prisma.InputJsonValue,
} as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
@@ -748,7 +748,7 @@ export const allocationRouter = createTRPCRouter({
entityType: "Assignment",
entityId: input.id,
action: "DELETE",
changes: { before: existing } as unknown as import("@planarchy/db").Prisma.InputJsonValue,
changes: { before: existing } as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
});
@@ -778,7 +778,7 @@ export const allocationRouter = createTRPCRouter({
entityType: "Allocation",
entityId: input.id,
action: "DELETE",
changes: { before: existing.entry } as unknown as import("@planarchy/db").Prisma.InputJsonValue,
changes: { before: existing.entry } as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
});
@@ -813,7 +813,7 @@ export const allocationRouter = createTRPCRouter({
action: "DELETE",
changes: {
before: existing.map((a) => ({ id: a.entry.id, projectId: a.projectId })),
} as unknown as import("@planarchy/db").Prisma.InputJsonValue,
} as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
});
+7 -7
View File
@@ -3,11 +3,11 @@
* Each tool has a JSON schema (for the AI) and an execute function (for the server).
*/
import { prisma } from "@planarchy/db";
import { calculateAllocation, checkDuplicateAssignment, countWorkingDays } from "@planarchy/engine/allocation";
import { computeBudgetStatus } from "@planarchy/engine";
import type { PermissionKey } from "@planarchy/shared";
import { parseTaskAction } from "@planarchy/shared";
import { prisma } from "@capakraken/db";
import { calculateAllocation, checkDuplicateAssignment, countWorkingDays } from "@capakraken/engine/allocation";
import { computeBudgetStatus } from "@capakraken/engine";
import type { PermissionKey } from "@capakraken/shared";
import { parseTaskAction } from "@capakraken/shared";
import { createAiClient, createDalleClient, isAiConfigured, isDalleConfigured, parseAiError } from "../ai-client.js";
import { getTaskAction } from "../lib/task-actions.js";
import { fmtEur } from "../lib/format-utils.js";
@@ -2691,7 +2691,7 @@ const executors = {
const vacation = await ctx.db.vacation.create({
data: {
resourceId: resource.id,
type: params.type as unknown as import("@planarchy/db").VacationType,
type: params.type as unknown as import("@capakraken/db").VacationType,
startDate: new Date(params.startDate),
endDate: new Date(params.endDate),
status: "PENDING",
@@ -5552,7 +5552,7 @@ const executors = {
return `Project "${project.name}" (${project.shortCode}): No active assignments — shoring ratio not available.`;
}
const { calculateShoringRatio: calcShoring } = await import("@planarchy/engine/allocation");
const { calculateShoringRatio: calcShoring } = await import("@capakraken/engine/allocation");
const mapped = assignments.map((a) => {
const start = new Date(a.startDate);
+3 -3
View File
@@ -5,7 +5,7 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { resolvePermissions, type PermissionOverrides, type SystemRole } from "@planarchy/shared";
import { resolvePermissions, type PermissionOverrides, type SystemRole } from "@capakraken/shared";
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
import { createAiClient, isAiConfigured, parseAiError } from "../ai-client.js";
import { TOOL_DEFINITIONS, executeTool, type ToolContext, type ToolAction } from "./assistant-tools.js";
@@ -148,12 +148,12 @@ export const assistantRouter = createTRPCRouter({
// Check write permission
const requiredPerm = TOOL_PERMISSION_MAP[toolName];
if (requiredPerm && !permissions.has(requiredPerm as import("@planarchy/shared").PermissionKey)) {
if (requiredPerm && !permissions.has(requiredPerm as import("@capakraken/shared").PermissionKey)) {
return false;
}
// Hide cost/budget tools if user lacks viewCosts
if (COST_TOOLS.has(toolName) && !permissions.has("viewCosts" as import("@planarchy/shared").PermissionKey)) {
if (COST_TOOLS.has(toolName) && !permissions.has("viewCosts" as import("@capakraken/shared").PermissionKey)) {
return false;
}
@@ -1,5 +1,5 @@
import { validateCustomFields } from "@planarchy/engine";
import { BlueprintTarget, type BlueprintFieldDefinition } from "@planarchy/shared";
import { validateCustomFields } from "@capakraken/engine";
import { BlueprintTarget, type BlueprintFieldDefinition } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { findUniqueOrThrow } from "../db/helpers.js";
+8 -8
View File
@@ -1,4 +1,4 @@
import { BlueprintTarget, CreateBlueprintSchema, UpdateBlueprintSchema, type BlueprintFieldDefinition } from "@planarchy/shared";
import { BlueprintTarget, CreateBlueprintSchema, UpdateBlueprintSchema, type BlueprintFieldDefinition } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -41,9 +41,9 @@ export const blueprintRouter = createTRPCRouter({
name: input.name,
target: input.target,
description: input.description,
fieldDefs: input.fieldDefs as unknown as import("@planarchy/db").Prisma.InputJsonValue,
defaults: input.defaults as unknown as import("@planarchy/db").Prisma.InputJsonValue,
validationRules: input.validationRules as unknown as import("@planarchy/db").Prisma.InputJsonValue,
fieldDefs: input.fieldDefs as unknown as import("@capakraken/db").Prisma.InputJsonValue,
defaults: input.defaults as unknown as import("@capakraken/db").Prisma.InputJsonValue,
validationRules: input.validationRules as unknown as import("@capakraken/db").Prisma.InputJsonValue,
} as unknown as Parameters<typeof ctx.db.blueprint.create>[0]["data"],
});
@@ -74,9 +74,9 @@ export const blueprintRouter = createTRPCRouter({
data: {
...(input.data.name !== undefined ? { name: input.data.name } : {}),
...(input.data.description !== undefined ? { description: input.data.description } : {}),
...(input.data.fieldDefs !== undefined ? { fieldDefs: input.data.fieldDefs as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.defaults !== undefined ? { defaults: input.data.defaults as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.validationRules !== undefined ? { validationRules: input.data.validationRules as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.fieldDefs !== undefined ? { fieldDefs: input.data.fieldDefs as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.defaults !== undefined ? { defaults: input.data.defaults as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.validationRules !== undefined ? { validationRules: input.data.validationRules as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
} as unknown as Parameters<typeof ctx.db.blueprint.update>[0]["data"],
});
@@ -105,7 +105,7 @@ export const blueprintRouter = createTRPCRouter({
);
const updated = await ctx.db.blueprint.update({
where: { id: input.id },
data: { rolePresets: input.rolePresets as unknown as import("@planarchy/db").Prisma.InputJsonValue },
data: { rolePresets: input.rolePresets as unknown as import("@capakraken/db").Prisma.InputJsonValue },
});
void createAuditEntry({
+1 -1
View File
@@ -1,7 +1,7 @@
import {
CreateCalculationRuleSchema,
UpdateCalculationRuleSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
import { PROJECT_BRIEF_SELECT } from "../db/selects.js";
@@ -10,11 +10,11 @@ import {
calculateAllocation,
DEFAULT_CALCULATION_RULES,
type AssignmentSlice,
} from "@planarchy/engine";
import type { CalculationRule, AbsenceDay } from "@planarchy/shared";
import type { SpainScheduleRule } from "@planarchy/shared";
import { isChargeabilityActualBooking, listAssignmentBookings } from "@planarchy/application";
import { VacationStatus } from "@planarchy/db";
} from "@capakraken/engine";
import type { CalculationRule, AbsenceDay } from "@capakraken/shared";
import type { SpainScheduleRule } from "@capakraken/shared";
import { isChargeabilityActualBooking, listAssignmentBookings } from "@capakraken/application";
import { VacationStatus } from "@capakraken/db";
import { z } from "zod";
import { createTRPCRouter, controllerProcedure } from "../trpc.js";
import { anonymizeResources, getAnonymizationDirectory } from "../lib/anonymization.js";
+2 -2
View File
@@ -1,11 +1,11 @@
import { CreateClientSchema, UpdateClientSchema } from "@planarchy/shared";
import { CreateClientSchema, UpdateClientSchema } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
import { createAuditEntry } from "../lib/audit.js";
import { adminProcedure, createTRPCRouter, managerProcedure, protectedProcedure } from "../trpc.js";
import type { ClientTree } from "@planarchy/shared";
import type { ClientTree } from "@capakraken/shared";
interface FlatClient {
id: string;
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { SystemRole } from "@planarchy/shared";
import { SystemRole } from "@capakraken/shared";
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
import { createNotification } from "../lib/create-notification.js";
import { createAuditEntry } from "../lib/audit.js";
+3 -3
View File
@@ -10,9 +10,9 @@ import {
computeEvenSpread,
distributeHoursToWeeks,
type AssignmentSlice,
} from "@planarchy/engine";
import type { CalculationRule, AbsenceDay, SpainScheduleRule, WeekdayAvailability } from "@planarchy/shared";
import { VacationStatus } from "@planarchy/db";
} from "@capakraken/engine";
import type { CalculationRule, AbsenceDay, SpainScheduleRule, WeekdayAvailability } from "@capakraken/shared";
import { VacationStatus } from "@capakraken/db";
import { z } from "zod";
import { createTRPCRouter, controllerProcedure } from "../trpc.js";
import { fmtEur } from "../lib/format-utils.js";
+2 -2
View File
@@ -3,8 +3,8 @@ import {
CreateMetroCitySchema,
UpdateCountrySchema,
UpdateMetroCitySchema,
} from "@planarchy/shared";
import { Prisma } from "@planarchy/db";
} from "@capakraken/shared";
import { Prisma } from "@capakraken/db";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -1,4 +1,4 @@
import { FieldType } from "@planarchy/shared";
import { FieldType } from "@capakraken/shared";
export interface CustomFieldFilterInput {
key: string;
+1 -1
View File
@@ -9,7 +9,7 @@ import {
getDashboardBudgetForecast,
getDashboardSkillGaps,
getDashboardProjectHealth,
} from "@planarchy/application";
} from "@capakraken/application";
import { anonymizeResources, getAnonymizationDirectory } from "../lib/anonymization.js";
import { cacheGet, cacheSet } from "../lib/cache.js";
+2 -2
View File
@@ -2,12 +2,12 @@ import {
ImportBatchStatus,
StagedRecordStatus,
DispoStagedRecordType,
} from "@planarchy/db";
} from "@capakraken/db";
import {
assessDispoImportReadiness,
commitDispoImportBatch,
stageDispoImportBatch,
} from "@planarchy/application";
} from "@capakraken/application";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { adminProcedure, createTRPCRouter } from "../trpc.js";
+2 -2
View File
@@ -3,12 +3,12 @@ import {
aggregateByDiscipline,
type EffortRuleInput,
type ScopeItemInput,
} from "@planarchy/engine";
} from "@capakraken/engine";
import {
CreateEffortRuleSetSchema,
UpdateEffortRuleSetSchema,
ApplyEffortRulesSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
+1 -1
View File
@@ -3,7 +3,7 @@
* Tracks annual leave quotas per resource per year.
* Balance is computed lazily: carryover from previous year is applied on first access.
*/
import { VacationType, VacationStatus } from "@planarchy/db";
import { VacationType, VacationStatus } from "@capakraken/db";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { RESOURCE_BRIEF_SELECT } from "../db/selects.js";
+4 -4
View File
@@ -9,8 +9,8 @@ import {
listEstimates,
submitEstimateVersion,
updateEstimateDraft,
} from "@planarchy/application";
import type { Prisma } from "@planarchy/db";
} from "@capakraken/application";
import type { Prisma } from "@capakraken/db";
import {
normalizeEstimateDemandLine,
summarizeEstimateDemandLines,
@@ -18,7 +18,7 @@ import {
distributeHoursToWeeks,
aggregateWeeklyToMonthly,
aggregateWeeklyByChapter,
} from "@planarchy/engine";
} from "@capakraken/engine";
import {
ApproveEstimateVersionSchema,
CloneEstimateSchema,
@@ -33,7 +33,7 @@ import {
SubmitEstimateVersionSchema,
UpdateCommercialTermsSchema,
UpdateEstimateDraftSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -2,12 +2,12 @@ import {
applyExperienceMultipliers,
applyExperienceMultipliersBatch,
type ExperienceMultiplierRule as EngineRule,
} from "@planarchy/engine";
} from "@capakraken/engine";
import {
CreateExperienceMultiplierSetSchema,
UpdateExperienceMultiplierSetSchema,
ApplyExperienceMultipliersSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
+2 -2
View File
@@ -1,5 +1,5 @@
import { BlueprintTarget, PermissionKey } from "@planarchy/shared";
import type { BlueprintFieldDefinition } from "@planarchy/shared";
import { BlueprintTarget, PermissionKey } from "@capakraken/shared";
import type { BlueprintFieldDefinition } from "@capakraken/shared";
import { z } from "zod";
import { controllerProcedure, createTRPCRouter, managerProcedure, requirePermission } from "../trpc.js";
+1 -1
View File
@@ -3,7 +3,7 @@ import {
CreateManagementLevelSchema,
UpdateManagementLevelGroupSchema,
UpdateManagementLevelSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
+2 -2
View File
@@ -1,11 +1,11 @@
import { CreateOrgUnitSchema, UpdateOrgUnitSchema } from "@planarchy/shared";
import { CreateOrgUnitSchema, UpdateOrgUnitSchema } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
import { createAuditEntry } from "../lib/audit.js";
import { adminProcedure, createTRPCRouter, protectedProcedure } from "../trpc.js";
import type { OrgUnitTree } from "@planarchy/shared";
import type { OrgUnitTree } from "@capakraken/shared";
interface FlatOrgUnit {
id: string;
@@ -1,6 +1,6 @@
import { buildSplitAllocationReadModel } from "@planarchy/application";
import type { PrismaClient } from "@planarchy/db";
import { AllocationStatus } from "@planarchy/shared";
import { buildSplitAllocationReadModel } from "@capakraken/application";
import type { PrismaClient } from "@capakraken/db";
import { AllocationStatus } from "@capakraken/shared";
import { ROLE_BRIEF_SELECT } from "../db/selects.js";
export const PROJECT_PLANNING_ALLOCATION_INCLUDE = {
+7 -7
View File
@@ -1,11 +1,11 @@
import {
countPlanningEntries,
listAssignmentBookings,
} from "@planarchy/application";
import { BlueprintTarget, CreateProjectSchema, FieldType, PermissionKey, ProjectStatus, UpdateProjectSchema } from "@planarchy/shared";
} from "@capakraken/application";
import { BlueprintTarget, CreateProjectSchema, FieldType, PermissionKey, ProjectStatus, UpdateProjectSchema } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { calculateShoringRatio, type ShoringAssignment } from "@planarchy/engine/allocation";
import { calculateShoringRatio, type ShoringAssignment } from "@capakraken/engine/allocation";
import { findUniqueOrThrow } from "../db/helpers.js";
import { paginate, paginateCursor, PaginationInputSchema, CursorInputSchema } from "../db/pagination.js";
import { assertBlueprintDynamicFields } from "./blueprint-validation.js";
@@ -185,8 +185,8 @@ export const projectRouter = createTRPCRouter({
status: input.status,
responsiblePerson: input.responsiblePerson,
...(input.color !== undefined ? { color: input.color } : {}),
staffingReqs: input.staffingReqs as unknown as import("@planarchy/db").Prisma.InputJsonValue,
dynamicFields: input.dynamicFields as unknown as import("@planarchy/db").Prisma.InputJsonValue,
staffingReqs: input.staffingReqs as unknown as import("@capakraken/db").Prisma.InputJsonValue,
dynamicFields: input.dynamicFields as unknown as import("@capakraken/db").Prisma.InputJsonValue,
blueprintId: input.blueprintId,
...(input.utilizationCategoryId !== undefined ? { utilizationCategoryId: input.utilizationCategoryId || null } : {}),
...(input.clientId !== undefined ? { clientId: input.clientId || null } : {}),
@@ -244,8 +244,8 @@ export const projectRouter = createTRPCRouter({
...(input.data.status !== undefined ? { status: input.data.status } : {}),
...(input.data.responsiblePerson !== undefined ? { responsiblePerson: input.data.responsiblePerson } : {}),
...(input.data.color !== undefined ? { color: input.data.color } : {}),
...(input.data.staffingReqs !== undefined ? { staffingReqs: input.data.staffingReqs as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.dynamicFields !== undefined ? { dynamicFields: input.data.dynamicFields as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.staffingReqs !== undefined ? { staffingReqs: input.data.staffingReqs as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.dynamicFields !== undefined ? { dynamicFields: input.data.dynamicFields as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.blueprintId !== undefined ? { blueprintId: input.data.blueprintId } : {}),
...(input.data.utilizationCategoryId !== undefined ? { utilizationCategoryId: input.data.utilizationCategoryId || null } : {}),
...(input.data.clientId !== undefined ? { clientId: input.data.clientId || null } : {}),
+2 -2
View File
@@ -1,10 +1,10 @@
import type { Prisma } from "@planarchy/db";
import type { Prisma } from "@capakraken/db";
import {
CreateRateCardLineSchema,
CreateRateCardSchema,
UpdateRateCardLineSchema,
UpdateRateCardSchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
+13 -13
View File
@@ -4,10 +4,10 @@ import {
isChargeabilityRelevantProject,
listAssignmentBookings,
recomputeResourceValueScores,
} from "@planarchy/application";
import { BlueprintTarget, CreateResourceSchema, FieldType, PermissionKey, ResourceRoleSchema, ResourceType, SkillEntrySchema, UpdateResourceSchema, inferStateFromPostalCode } from "@planarchy/shared";
import type { WeekdayAvailability } from "@planarchy/shared";
import { computeChargeability } from "@planarchy/engine";
} from "@capakraken/application";
import { BlueprintTarget, CreateResourceSchema, FieldType, PermissionKey, ResourceRoleSchema, ResourceType, SkillEntrySchema, UpdateResourceSchema, inferStateFromPostalCode } from "@capakraken/shared";
import type { WeekdayAvailability } from "@capakraken/shared";
import { computeChargeability } from "@capakraken/engine";
import { assertBlueprintDynamicFields } from "./blueprint-validation.js";
import { buildDynamicFieldWhereClauses } from "./custom-field-filters.js";
import {
@@ -419,8 +419,8 @@ export const resourceRouter = createTRPCRouter({
currency: input.currency,
chargeabilityTarget: input.chargeabilityTarget,
availability: input.availability,
skills: input.skills as unknown as import("@planarchy/db").Prisma.InputJsonValue,
dynamicFields: input.dynamicFields as unknown as import("@planarchy/db").Prisma.InputJsonValue,
skills: input.skills as unknown as import("@capakraken/db").Prisma.InputJsonValue,
dynamicFields: input.dynamicFields as unknown as import("@capakraken/db").Prisma.InputJsonValue,
blueprintId: input.blueprintId,
portfolioUrl: input.portfolioUrl || undefined,
roleId: input.roleId || undefined,
@@ -506,9 +506,9 @@ export const resourceRouter = createTRPCRouter({
...(input.data.ucrCents !== undefined ? { ucrCents: input.data.ucrCents } : {}),
...(input.data.currency !== undefined ? { currency: input.data.currency } : {}),
...(input.data.chargeabilityTarget !== undefined ? { chargeabilityTarget: input.data.chargeabilityTarget } : {}),
...(input.data.availability !== undefined ? { availability: input.data.availability as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.skills !== undefined ? { skills: input.data.skills as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.dynamicFields !== undefined ? { dynamicFields: input.data.dynamicFields as unknown as import("@planarchy/db").Prisma.InputJsonValue } : {}),
...(input.data.availability !== undefined ? { availability: input.data.availability as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.skills !== undefined ? { skills: input.data.skills as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.dynamicFields !== undefined ? { dynamicFields: input.data.dynamicFields as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
...(input.data.blueprintId !== undefined ? { blueprintId: input.data.blueprintId } : {}),
...(input.data.isActive !== undefined ? { isActive: input.data.isActive } : {}),
...(input.data.portfolioUrl !== undefined ? { portfolioUrl: input.data.portfolioUrl || null } : {}),
@@ -648,7 +648,7 @@ export const resourceRouter = createTRPCRouter({
await ctx.db.resource.update({
where: { id: resourceId },
data: {
skills: input.skills as unknown as import("@planarchy/db").Prisma.InputJsonValue,
skills: input.skills as unknown as import("@capakraken/db").Prisma.InputJsonValue,
skillMatrixUpdatedAt: new Date(),
...(input.employeeInfo?.portfolioUrl !== undefined
? { portfolioUrl: input.employeeInfo.portfolioUrl || null }
@@ -684,7 +684,7 @@ export const resourceRouter = createTRPCRouter({
await ctx.db.resource.update({
where: { id: input.resourceId },
data: {
skills: input.skills as unknown as import("@planarchy/db").Prisma.InputJsonValue,
skills: input.skills as unknown as import("@capakraken/db").Prisma.InputJsonValue,
skillMatrixUpdatedAt: new Date(),
...(input.employeeInfo?.portfolioUrl !== undefined
? { portfolioUrl: input.employeeInfo.portfolioUrl || null }
@@ -731,7 +731,7 @@ export const resourceRouter = createTRPCRouter({
ctx.db.resource.update({
where: { id: eidToId.get(entry.eid)! },
data: {
skills: entry.skills as unknown as import("@planarchy/db").Prisma.InputJsonValue,
skills: entry.skills as unknown as import("@capakraken/db").Prisma.InputJsonValue,
skillMatrixUpdatedAt: now,
...(entry.employeeInfo?.portfolioUrl !== undefined
? { portfolioUrl: entry.employeeInfo.portfolioUrl || null }
@@ -1185,7 +1185,7 @@ export const resourceRouter = createTRPCRouter({
entityType: "Resource",
entityId: input.ids.join(","),
action: "UPDATE",
changes: { after: { dynamicFields: input.fields, ids: input.ids } } as unknown as import("@planarchy/db").Prisma.InputJsonValue,
changes: { after: { dynamicFields: input.fields, ids: input.ids } } as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
+5 -5
View File
@@ -1,5 +1,5 @@
import { countPlanningEntries } from "@planarchy/application";
import { CreateRoleSchema, PermissionKey, UpdateRoleSchema } from "@planarchy/shared";
import { countPlanningEntries } from "@capakraken/application";
import { CreateRoleSchema, PermissionKey, UpdateRoleSchema } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -8,7 +8,7 @@ import { emitRoleCreated, emitRoleDeleted, emitRoleUpdated } from "../sse/event-
import { createTRPCRouter, managerProcedure, protectedProcedure, requirePermission } from "../trpc.js";
async function loadRolePlanningEntryCounts(
db: Pick<import("@planarchy/db").PrismaClient, "demandRequirement" | "assignment">,
db: Pick<import("@capakraken/db").PrismaClient, "demandRequirement" | "assignment">,
roleIds: string[],
) {
const { countsByRoleId } = await countPlanningEntries(db, {
@@ -24,7 +24,7 @@ async function attachPlanningEntryCounts<
_count: { resourceRoles: number };
},
>(
db: Pick<import("@planarchy/db").PrismaClient, "demandRequirement" | "assignment">,
db: Pick<import("@capakraken/db").PrismaClient, "demandRequirement" | "assignment">,
roles: TRole[],
): Promise<Array<TRole & { _count: { resourceRoles: number; allocations: number } }>> {
const countsByRoleId = await loadRolePlanningEntryCounts(
@@ -47,7 +47,7 @@ async function attachSinglePlanningEntryCount<
_count: { resourceRoles: number };
},
>(
db: Pick<import("@planarchy/db").PrismaClient, "demandRequirement" | "assignment">,
db: Pick<import("@capakraken/db").PrismaClient, "demandRequirement" | "assignment">,
role: TRole,
): Promise<TRole & { _count: { resourceRoles: number; allocations: number } }> {
return (await attachPlanningEntryCounts(db, [role]))[0]!;
+1 -1
View File
@@ -1,4 +1,4 @@
import { calculateAllocation, countWorkingDays } from "@planarchy/engine/allocation";
import { calculateAllocation, countWorkingDays } from "@capakraken/engine/allocation";
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, controllerProcedure, protectedProcedure } from "../trpc.js";
+1 -1
View File
@@ -2,7 +2,7 @@ import { z } from "zod";
import { adminProcedure, createTRPCRouter, protectedProcedure } from "../trpc.js";
import { createAiClient, isAiConfigured, parseAiError } from "../ai-client.js";
import { DEFAULT_SUMMARY_PROMPT } from "./resource.js";
import { VALUE_SCORE_WEIGHTS } from "@planarchy/shared";
import { VALUE_SCORE_WEIGHTS } from "@capakraken/shared";
import { testSmtpConnection } from "../lib/email.js";
import { createAuditEntry } from "../lib/audit.js";
+6 -6
View File
@@ -1,5 +1,5 @@
import { analyzeUtilization, findCapacityWindows, rankResources } from "@planarchy/staffing";
import { listAssignmentBookings } from "@planarchy/application";
import { analyzeUtilization, findCapacityWindows, rankResources } from "@capakraken/staffing";
import { listAssignmentBookings } from "@capakraken/application";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -69,7 +69,7 @@ export const staffingRouter = createTRPCRouter({
id: resource.id,
displayName: resource.displayName,
eid: resource.eid,
skills: skills as unknown as import("@planarchy/shared").SkillEntry[],
skills: skills as unknown as import("@capakraken/shared").SkillEntry[],
lcrCents: resource.lcrCents,
chargeabilityTarget: resource.chargeabilityTarget,
currentUtilizationPercent: utilizationPercent,
@@ -133,7 +133,7 @@ export const staffingRouter = createTRPCRouter({
id: resource.id,
displayName: resource.displayName,
chargeabilityTarget: resource.chargeabilityTarget,
availability: resource.availability as unknown as import("@planarchy/shared").WeekdayAvailability,
availability: resource.availability as unknown as import("@capakraken/shared").WeekdayAvailability,
},
allocations: resourceBookings.map((booking) => ({
startDate: booking.startDate,
@@ -183,14 +183,14 @@ export const staffingRouter = createTRPCRouter({
{
id: resource.id,
displayName: resource.displayName,
availability: resource.availability as unknown as import("@planarchy/shared").WeekdayAvailability,
availability: resource.availability as unknown as import("@capakraken/shared").WeekdayAvailability,
},
resourceBookings.map((booking) => ({
startDate: booking.startDate,
endDate: booking.endDate,
hoursPerDay: booking.hoursPerDay,
status: booking.status,
})) as Pick<import("@planarchy/shared").Allocation, "startDate" | "endDate" | "hoursPerDay" | "status">[],
})) as Pick<import("@capakraken/shared").Allocation, "startDate" | "endDate" | "hoursPerDay" | "status">[],
input.startDate,
input.endDate,
input.minAvailableHoursPerDay,
@@ -2,9 +2,9 @@ import {
buildSplitAllocationReadModel,
type SplitAssignmentRecord,
type SplitDemandRequirementRecord,
} from "@planarchy/application";
import type { ShiftInput } from "@planarchy/engine";
import type { WeekdayAvailability } from "@planarchy/shared";
} from "@capakraken/application";
import type { ShiftInput } from "@capakraken/engine";
import type { WeekdayAvailability } from "@capakraken/shared";
export interface TimelineShiftWindow {
id: string;
+12 -12
View File
@@ -7,12 +7,12 @@ import {
updateAssignment,
updateDemandRequirement,
updateAllocationEntry,
} from "@planarchy/application";
import type { PrismaClient } from "@planarchy/db";
import { calculateAllocation, computeBudgetStatus, validateShift, DEFAULT_CALCULATION_RULES } from "@planarchy/engine";
import type { CalculationRule, AbsenceDay } from "@planarchy/shared";
import { VacationType } from "@planarchy/db";
import { AllocationStatus, PermissionKey, ShiftProjectSchema, UpdateAllocationHoursSchema } from "@planarchy/shared";
} from "@capakraken/application";
import type { PrismaClient } from "@capakraken/db";
import { calculateAllocation, computeBudgetStatus, validateShift, DEFAULT_CALCULATION_RULES } from "@capakraken/engine";
import type { CalculationRule, AbsenceDay } from "@capakraken/shared";
import { VacationType } from "@capakraken/db";
import { AllocationStatus, PermissionKey, ShiftProjectSchema, UpdateAllocationHoursSchema } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -433,10 +433,10 @@ export const timelineRouter = createTRPCRouter({
}
const availability =
existingResource.availability as unknown as import("@planarchy/shared").WeekdayAvailability;
existingResource.availability as unknown as import("@capakraken/shared").WeekdayAvailability;
// Load recurrence from merged metadata
const recurrence = (newMeta.recurrence as import("@planarchy/shared").RecurrencePattern | undefined);
const recurrence = (newMeta.recurrence as import("@capakraken/shared").RecurrencePattern | undefined);
// Load typed absences + calculation rules for rules-aware cost computation
const [absenceData, calculationRules] = await Promise.all([
@@ -614,7 +614,7 @@ export const timelineRouter = createTRPCRouter({
startDate: newStartDate,
endDate: newEndDate,
availability:
assignment.resource!.availability as unknown as import("@planarchy/shared").WeekdayAvailability,
assignment.resource!.availability as unknown as import("@capakraken/shared").WeekdayAvailability,
includeSaturday,
vacationDates: shiftAbsenceData.legacyVacationDates,
absenceDays: shiftAbsenceData.absenceDays,
@@ -642,7 +642,7 @@ export const timelineRouter = createTRPCRouter({
before: { startDate: project.startDate, endDate: project.endDate },
after: { startDate: newStartDate, endDate: newEndDate },
costImpact: validation.costImpact,
} as unknown as import("@planarchy/db").Prisma.InputJsonValue,
} as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
@@ -876,7 +876,7 @@ export const timelineRouter = createTRPCRouter({
mode: input.mode,
daysDelta: input.daysDelta,
count: resolved.length,
} as unknown as import("@planarchy/db").Prisma.InputJsonValue,
} as unknown as import("@capakraken/db").Prisma.InputJsonValue,
},
});
@@ -929,7 +929,7 @@ export const timelineRouter = createTRPCRouter({
startDate: booking.startDate,
endDate: booking.endDate,
hoursPerDay: booking.hoursPerDay,
})) as unknown as Pick<import("@planarchy/shared").Allocation, "status" | "dailyCostCents" | "startDate" | "endDate" | "hoursPerDay">[],
})) as unknown as Pick<import("@capakraken/shared").Allocation, "status" | "dailyCostCents" | "startDate" | "endDate" | "hoursPerDay">[],
project.startDate,
project.endDate,
);
+6 -6
View File
@@ -3,12 +3,12 @@ import {
SystemRole,
resolvePermissions,
type ColumnPreferences,
} from "@planarchy/shared/types";
} from "@capakraken/shared/types";
import {
dashboardLayoutSchema,
normalizeDashboardLayout,
} from "@planarchy/shared/schemas";
import { Prisma } from "@planarchy/db";
} from "@capakraken/shared/schemas";
import { Prisma } from "@capakraken/db";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
@@ -297,7 +297,7 @@ export const userRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const updated = await ctx.db.user.update({
where: { email: ctx.session.user?.email ?? "" },
data: { dashboardLayout: input.layout as unknown as import("@planarchy/db").Prisma.InputJsonValue },
data: { dashboardLayout: input.layout as unknown as import("@capakraken/db").Prisma.InputJsonValue },
select: { updatedAt: true },
});
return { updatedAt: updated.updatedAt };
@@ -422,10 +422,10 @@ export const userRouter = createTRPCRouter({
select: { columnPreferences: true },
});
const prefs = (existing?.columnPreferences ?? {}) as ColumnPreferences;
const prev = (prefs[input.view] as import("@planarchy/shared").ViewPreferences | undefined) ?? { visible: [] };
const prev = (prefs[input.view] as import("@capakraken/shared").ViewPreferences | undefined) ?? { visible: [] };
// Merge: only overwrite fields that were explicitly provided
const merged: import("@planarchy/shared").ViewPreferences = {
const merged: import("@capakraken/shared").ViewPreferences = {
visible: input.visible ?? prev.visible,
};
// sort: null = clear, undefined = keep existing, value = set
@@ -1,7 +1,7 @@
import {
CreateUtilizationCategorySchema,
UpdateUtilizationCategorySchema,
} from "@planarchy/shared";
} from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
+2 -2
View File
@@ -1,5 +1,5 @@
import { UpdateVacationStatusSchema, getPublicHolidays, buildTaskAction } from "@planarchy/shared";
import { VacationStatus, VacationType } from "@planarchy/db";
import { UpdateVacationStatusSchema, getPublicHolidays, buildTaskAction } from "@capakraken/shared";
import { VacationStatus, VacationType } from "@capakraken/db";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
+2 -2
View File
@@ -1,5 +1,5 @@
import { Redis } from "ioredis";
import { SSE_EVENT_TYPES, type SseEventType } from "@planarchy/shared";
import { SSE_EVENT_TYPES, type SseEventType } from "@capakraken/shared";
export interface SseEvent {
type: SseEventType;
@@ -78,7 +78,7 @@ export function cancelPendingEvents(): void {
// Redis connection — use env var REDIS_URL or fallback to default dev URL
const REDIS_URL = process.env["REDIS_URL"] ?? "redis://localhost:6380";
const CHANNEL = "planarchy:sse";
const CHANNEL = "capakraken:sse";
let publisher: Redis | null = null;
let subscriber: Redis | null = null;
+4 -4
View File
@@ -1,5 +1,5 @@
import { prisma } from "@planarchy/db";
import { resolvePermissions, PermissionKey, SystemRole } from "@planarchy/shared";
import { prisma } from "@capakraken/db";
import { resolvePermissions, PermissionKey, SystemRole } from "@capakraken/shared";
import { initTRPC, TRPCError } from "@trpc/server";
import { ZodError } from "zod";
import { loggingMiddleware } from "./middleware/logging.js";
@@ -122,7 +122,7 @@ export const managerProcedure = protectedProcedure.use(({ ctx, next }) => {
}
const permissions = resolvePermissions(
user.systemRole as SystemRole,
user.permissionOverrides as import("@planarchy/shared").PermissionOverrides | null,
user.permissionOverrides as import("@capakraken/shared").PermissionOverrides | null,
ctx.roleDefaults ?? undefined,
);
return next({ ctx: { ...ctx, user, permissions } });
@@ -141,7 +141,7 @@ export const controllerProcedure = protectedProcedure.use(({ ctx, next }) => {
}
const permissions = resolvePermissions(
user.systemRole as SystemRole,
user.permissionOverrides as import("@planarchy/shared").PermissionOverrides | null,
user.permissionOverrides as import("@capakraken/shared").PermissionOverrides | null,
ctx.roleDefaults ?? undefined,
);
return next({ ctx: { ...ctx, user, permissions } });
+1 -1
View File
@@ -1,5 +1,5 @@
{
"extends": "@planarchy/tsconfig/base.json",
"extends": "@capakraken/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"