Files
CapaKraken/apps/web/src/lib/blueprint-field-catalog.ts
T
Hartmut cd78f72f33 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>
2026-03-27 13:18:09 +01:00

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);
}