cd78f72f33
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>
518 lines
15 KiB
TypeScript
518 lines
15 KiB
TypeScript
import { FieldType, BlueprintTarget } from "@capakraken/shared";
|
|
import type { FieldOption } from "@capakraken/shared";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Catalog types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export interface CatalogField {
|
|
key: string;
|
|
label: string;
|
|
type: FieldType;
|
|
category: string;
|
|
description: string;
|
|
options?: FieldOption[];
|
|
defaultValue?: unknown;
|
|
/** true = maps to a real model column; false = stored in dynamicFields JSONB */
|
|
builtIn: boolean;
|
|
}
|
|
|
|
export interface CatalogCategory {
|
|
name: string;
|
|
description: string;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// PROJECT catalog
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const PROJECT_CATEGORIES: CatalogCategory[] = [
|
|
{ name: "Client & Billing", description: "Client relationship and billing details" },
|
|
{ name: "Technical Specs", description: "Render pipeline and delivery format" },
|
|
{ name: "Scope & Delivery", description: "Approval rounds, revision budgets, complexity" },
|
|
];
|
|
|
|
export const PROJECT_FIELD_CATALOG: CatalogField[] = [
|
|
// -- Client & Billing --
|
|
{
|
|
key: "clientUnit",
|
|
label: "Client Unit",
|
|
type: FieldType.TEXT,
|
|
category: "Client & Billing",
|
|
description: "Business unit or division of the client",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "personHoursSold",
|
|
label: "Person-Hours Sold",
|
|
type: FieldType.NUMBER,
|
|
category: "Client & Billing",
|
|
description: "Total billable person-hours sold to the client",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "billingModel",
|
|
label: "Billing Model",
|
|
type: FieldType.SELECT,
|
|
category: "Client & Billing",
|
|
description: "How the project is billed",
|
|
options: [
|
|
{ value: "fixed", label: "Fixed Price" },
|
|
{ value: "tm", label: "Time & Material" },
|
|
{ value: "hybrid", label: "Hybrid" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "poNumber",
|
|
label: "PO Number",
|
|
type: FieldType.TEXT,
|
|
category: "Client & Billing",
|
|
description: "Purchase order reference number",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "invoiceCycle",
|
|
label: "Invoice Cycle",
|
|
type: FieldType.SELECT,
|
|
category: "Client & Billing",
|
|
description: "How often invoices are sent",
|
|
options: [
|
|
{ value: "weekly", label: "Weekly" },
|
|
{ value: "biweekly", label: "Bi-weekly" },
|
|
{ value: "monthly", label: "Monthly" },
|
|
{ value: "milestone", label: "Per Milestone" },
|
|
{ value: "on_completion", label: "On Completion" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
|
|
// -- Technical Specs --
|
|
{
|
|
key: "renderEngine",
|
|
label: "Render Engine",
|
|
type: FieldType.SELECT,
|
|
category: "Technical Specs",
|
|
description: "Primary render engine used",
|
|
options: [
|
|
{ value: "vray", label: "V-Ray" },
|
|
{ value: "arnold", label: "Arnold" },
|
|
{ value: "redshift", label: "Redshift" },
|
|
{ value: "octane", label: "Octane" },
|
|
{ value: "cycles", label: "Cycles" },
|
|
{ value: "unreal", label: "Unreal Engine" },
|
|
{ value: "unity", label: "Unity" },
|
|
{ value: "other", label: "Other" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "renderFarm",
|
|
label: "Render Farm",
|
|
type: FieldType.SELECT,
|
|
category: "Technical Specs",
|
|
description: "Render farm provider",
|
|
options: [
|
|
{ value: "internal", label: "Internal" },
|
|
{ value: "rebusfarm", label: "RebusFarm" },
|
|
{ value: "ranch", label: "Ranch Computing" },
|
|
{ value: "garagefarm", label: "GarageFarm" },
|
|
{ value: "aws", label: "AWS Deadline" },
|
|
{ value: "other", label: "Other" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "deliveryFormat",
|
|
label: "Delivery Format",
|
|
type: FieldType.MULTI_SELECT,
|
|
category: "Technical Specs",
|
|
description: "Final deliverable formats",
|
|
options: [
|
|
{ value: "exr", label: "EXR" },
|
|
{ value: "png", label: "PNG" },
|
|
{ value: "mp4", label: "MP4 (H.264)" },
|
|
{ value: "mov_prores", label: "MOV (ProRes)" },
|
|
{ value: "tiff", label: "TIFF" },
|
|
{ value: "dpx", label: "DPX" },
|
|
{ value: "fbx", label: "FBX" },
|
|
{ value: "glb", label: "GLB/glTF" },
|
|
{ value: "usd", label: "USD" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "frameRate",
|
|
label: "Frame Rate",
|
|
type: FieldType.SELECT,
|
|
category: "Technical Specs",
|
|
description: "Target frame rate for animation/video",
|
|
options: [
|
|
{ value: "24", label: "24 fps (Film)" },
|
|
{ value: "25", label: "25 fps (PAL)" },
|
|
{ value: "30", label: "30 fps (NTSC)" },
|
|
{ value: "48", label: "48 fps (HFR)" },
|
|
{ value: "60", label: "60 fps" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "colorSpace",
|
|
label: "Color Space",
|
|
type: FieldType.SELECT,
|
|
category: "Technical Specs",
|
|
description: "Working color space",
|
|
options: [
|
|
{ value: "srgb", label: "sRGB" },
|
|
{ value: "aces", label: "ACES" },
|
|
{ value: "rec709", label: "Rec.709" },
|
|
{ value: "rec2020", label: "Rec.2020" },
|
|
{ value: "display_p3", label: "Display P3" },
|
|
{ value: "linear", label: "Linear" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "resolution",
|
|
label: "Resolution",
|
|
type: FieldType.SELECT,
|
|
category: "Technical Specs",
|
|
description: "Output resolution",
|
|
options: [
|
|
{ value: "hd", label: "1920x1080 (Full HD)" },
|
|
{ value: "2k", label: "2048x1080 (2K)" },
|
|
{ value: "qhd", label: "2560x1440 (QHD)" },
|
|
{ value: "uhd", label: "3840x2160 (4K UHD)" },
|
|
{ value: "4k_dci", label: "4096x2160 (4K DCI)" },
|
|
{ value: "8k", label: "7680x4320 (8K)" },
|
|
{ value: "custom", label: "Custom" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
|
|
// -- Scope & Delivery --
|
|
{
|
|
key: "clientApprovalRounds",
|
|
label: "Client Approval Rounds",
|
|
type: FieldType.NUMBER,
|
|
category: "Scope & Delivery",
|
|
description: "Number of approval rounds included in the scope",
|
|
defaultValue: 2,
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "revisionBudgetHours",
|
|
label: "Revision Budget (hours)",
|
|
type: FieldType.NUMBER,
|
|
category: "Scope & Delivery",
|
|
description: "Hours reserved for client-requested revisions",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "complexityLevel",
|
|
label: "Complexity Level",
|
|
type: FieldType.SELECT,
|
|
category: "Scope & Delivery",
|
|
description: "Overall project complexity assessment",
|
|
options: [
|
|
{ value: "low", label: "Low" },
|
|
{ value: "medium", label: "Medium" },
|
|
{ value: "high", label: "High" },
|
|
{ value: "very_high", label: "Very High" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "shotCount",
|
|
label: "Shot Count",
|
|
type: FieldType.NUMBER,
|
|
category: "Scope & Delivery",
|
|
description: "Total number of shots or scenes",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "deliveryDate",
|
|
label: "Delivery Date",
|
|
type: FieldType.DATE,
|
|
category: "Scope & Delivery",
|
|
description: "Final delivery deadline to the client",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "nda",
|
|
label: "NDA Required",
|
|
type: FieldType.BOOLEAN,
|
|
category: "Scope & Delivery",
|
|
description: "Whether a non-disclosure agreement is in effect",
|
|
defaultValue: false,
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "projectBrief",
|
|
label: "Project Brief URL",
|
|
type: FieldType.URL,
|
|
category: "Scope & Delivery",
|
|
description: "Link to the project brief or scope document",
|
|
builtIn: false,
|
|
},
|
|
];
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// RESOURCE catalog
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const RESOURCE_CATEGORIES: CatalogCategory[] = [
|
|
{ name: "Person Info", description: "Basic employee information" },
|
|
{ name: "Organization", description: "Organizational placement and location" },
|
|
{ name: "Contract", description: "Contract terms and rates" },
|
|
{ name: "Skills & Work", description: "Technical skills and work preferences" },
|
|
];
|
|
|
|
export const RESOURCE_FIELD_CATALOG: CatalogField[] = [
|
|
// -- Person Info --
|
|
{
|
|
key: "nickname",
|
|
label: "Nickname",
|
|
type: FieldType.TEXT,
|
|
category: "Person Info",
|
|
description: "Preferred name or nickname",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "phone",
|
|
label: "Phone Number",
|
|
type: FieldType.TEXT,
|
|
category: "Person Info",
|
|
description: "Business phone number",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "personalEmail",
|
|
label: "Personal Email",
|
|
type: FieldType.EMAIL,
|
|
category: "Person Info",
|
|
description: "Personal/secondary email address",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "linkedInUrl",
|
|
label: "LinkedIn Profile",
|
|
type: FieldType.URL,
|
|
category: "Person Info",
|
|
description: "Link to LinkedIn profile",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "startDate",
|
|
label: "Start Date",
|
|
type: FieldType.DATE,
|
|
category: "Person Info",
|
|
description: "Employment start date",
|
|
builtIn: false,
|
|
},
|
|
|
|
// -- Organization --
|
|
{
|
|
key: "department",
|
|
label: "Department",
|
|
type: FieldType.TEXT,
|
|
category: "Organization",
|
|
description: "Department or team name",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "costCenter",
|
|
label: "Cost Center",
|
|
type: FieldType.TEXT,
|
|
category: "Organization",
|
|
description: "Accounting cost center code",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "officeLocation",
|
|
label: "Office Location",
|
|
type: FieldType.TEXT,
|
|
category: "Organization",
|
|
description: "Physical office location or site name",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "reportingTo",
|
|
label: "Reporting To",
|
|
type: FieldType.TEXT,
|
|
category: "Organization",
|
|
description: "Direct manager or supervisor name",
|
|
builtIn: false,
|
|
},
|
|
|
|
// -- Contract --
|
|
{
|
|
key: "contractType",
|
|
label: "Contract Type",
|
|
type: FieldType.SELECT,
|
|
category: "Contract",
|
|
description: "Type of employment contract",
|
|
options: [
|
|
{ value: "permanent", label: "Permanent" },
|
|
{ value: "fixed_term", label: "Fixed Term" },
|
|
{ value: "freelance", label: "Freelance" },
|
|
{ value: "internship", label: "Internship" },
|
|
{ value: "working_student", label: "Working Student" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "contractEndDate",
|
|
label: "Contract End Date",
|
|
type: FieldType.DATE,
|
|
category: "Contract",
|
|
description: "End date for fixed-term contracts",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "probationEndDate",
|
|
label: "Probation End Date",
|
|
type: FieldType.DATE,
|
|
category: "Contract",
|
|
description: "End of probationary period",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "weeklyHours",
|
|
label: "Weekly Hours",
|
|
type: FieldType.NUMBER,
|
|
category: "Contract",
|
|
description: "Contracted weekly working hours",
|
|
defaultValue: 40,
|
|
builtIn: false,
|
|
},
|
|
|
|
// -- Skills & Work --
|
|
{
|
|
key: "primarySoftware",
|
|
label: "Primary Software",
|
|
type: FieldType.MULTI_SELECT,
|
|
category: "Skills & Work",
|
|
description: "Main software tools used",
|
|
options: [
|
|
{ value: "maya", label: "Maya" },
|
|
{ value: "3dsmax", label: "3ds Max" },
|
|
{ value: "blender", label: "Blender" },
|
|
{ value: "cinema4d", label: "Cinema 4D" },
|
|
{ value: "houdini", label: "Houdini" },
|
|
{ value: "zbrush", label: "ZBrush" },
|
|
{ value: "substance", label: "Substance 3D" },
|
|
{ value: "nuke", label: "Nuke" },
|
|
{ value: "aftereffects", label: "After Effects" },
|
|
{ value: "unreal", label: "Unreal Engine" },
|
|
{ value: "unity", label: "Unity" },
|
|
{ value: "photoshop", label: "Photoshop" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "yearsOfExperience",
|
|
label: "Years of Experience",
|
|
type: FieldType.NUMBER,
|
|
category: "Skills & Work",
|
|
description: "Total years of professional experience",
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "spokenLanguages",
|
|
label: "Spoken Languages",
|
|
type: FieldType.MULTI_SELECT,
|
|
category: "Skills & Work",
|
|
description: "Languages the person speaks",
|
|
options: [
|
|
{ value: "de", label: "German" },
|
|
{ value: "en", label: "English" },
|
|
{ value: "fr", label: "French" },
|
|
{ value: "es", label: "Spanish" },
|
|
{ value: "it", label: "Italian" },
|
|
{ value: "pt", label: "Portuguese" },
|
|
{ value: "zh", label: "Chinese" },
|
|
{ value: "ja", label: "Japanese" },
|
|
{ value: "ko", label: "Korean" },
|
|
{ value: "ru", label: "Russian" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "timezone",
|
|
label: "Timezone",
|
|
type: FieldType.SELECT,
|
|
category: "Skills & Work",
|
|
description: "Primary working timezone",
|
|
options: [
|
|
{ value: "Europe/Berlin", label: "CET (Berlin)" },
|
|
{ value: "Europe/London", label: "GMT (London)" },
|
|
{ value: "America/New_York", label: "EST (New York)" },
|
|
{ value: "America/Los_Angeles", label: "PST (Los Angeles)" },
|
|
{ value: "Asia/Tokyo", label: "JST (Tokyo)" },
|
|
{ value: "Asia/Shanghai", label: "CST (Shanghai)" },
|
|
{ value: "Asia/Kolkata", label: "IST (Mumbai)" },
|
|
{ value: "Australia/Sydney", label: "AEDT (Sydney)" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "remoteEligible",
|
|
label: "Remote Eligible",
|
|
type: FieldType.BOOLEAN,
|
|
category: "Skills & Work",
|
|
description: "Whether the person can work remotely",
|
|
defaultValue: false,
|
|
builtIn: false,
|
|
},
|
|
{
|
|
key: "specialization",
|
|
label: "Specialization",
|
|
type: FieldType.SELECT,
|
|
category: "Skills & Work",
|
|
description: "Primary area of specialization",
|
|
options: [
|
|
{ value: "modeling", label: "3D Modeling" },
|
|
{ value: "texturing", label: "Texturing" },
|
|
{ value: "rigging", label: "Rigging" },
|
|
{ value: "animation", label: "Animation" },
|
|
{ value: "lighting", label: "Lighting" },
|
|
{ value: "rendering", label: "Rendering" },
|
|
{ value: "compositing", label: "Compositing" },
|
|
{ value: "fx", label: "FX / Simulation" },
|
|
{ value: "concept", label: "Concept Art" },
|
|
{ value: "motion_design", label: "Motion Design" },
|
|
{ value: "td", label: "Technical Direction" },
|
|
{ value: "pipeline", label: "Pipeline / Tools" },
|
|
{ value: "generalist", label: "Generalist" },
|
|
],
|
|
builtIn: false,
|
|
},
|
|
];
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/** Return the catalog for a given blueprint target */
|
|
export function getCatalogForTarget(target: BlueprintTarget | string): CatalogField[] {
|
|
return target === BlueprintTarget.PROJECT
|
|
? PROJECT_FIELD_CATALOG
|
|
: RESOURCE_FIELD_CATALOG;
|
|
}
|
|
|
|
/** Return the categories for a given blueprint target */
|
|
export function getCategoriesForTarget(target: BlueprintTarget | string): CatalogCategory[] {
|
|
return target === BlueprintTarget.PROJECT
|
|
? PROJECT_CATEGORIES
|
|
: RESOURCE_CATEGORIES;
|
|
}
|
|
|
|
/** Look up a catalog field by key */
|
|
export function findCatalogField(
|
|
target: BlueprintTarget | string,
|
|
key: string,
|
|
): CatalogField | undefined {
|
|
return getCatalogForTarget(target).find((f) => f.key === key);
|
|
}
|