feat: project cover art with AI generation, branding rename, RBAC fix, computation graph

- Add DALL-E cover art generation for projects (Azure OpenAI + standard OpenAI)
- CoverArtSection component with generate/upload/remove/focus-point controls
- Client-side image compression (10MB input → WebP/JPEG, max 1920px)
- DALL-E settings in admin panel (deployment, endpoint, API key)
- MCP assistant tools for cover art (generate_project_cover, remove_project_cover)
- Rename "Planarchy" → "plANARCHY" across all UI-facing text (13 files)
- Fix hardcoded canEdit={true} on project detail page — now checks user role
- Computation graph visualization (2D/3D) for calculation rules
- OG image and OpenGraph metadata

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-03-18 11:31:56 +01:00
parent 21af720f90
commit 093e13b88f
86 changed files with 5623 additions and 744 deletions
@@ -6,6 +6,7 @@ import { OrderType, AllocationType, ProjectStatus } from "@planarchy/shared";
import type { Project } from "@planarchy/shared";
import { trpc } from "~/lib/trpc/client.js";
import { DateInput } from "~/components/ui/DateInput.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
const ORDER_TYPE_OPTIONS = [
{ value: "BD", label: "BD" },
@@ -283,6 +284,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="shortCode">
Chargecode <span className="text-red-500">*</span>
<InfoTooltip content="Unique project identifier for time tracking and cost attribution. Cannot be changed after creation." />
</label>
<input
id="shortCode"
@@ -306,6 +308,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="name">
Name <span className="text-red-500">*</span>
<InfoTooltip content="Display name shown on the timeline and in reports." />
</label>
<input
id="name"
@@ -331,6 +334,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="orderType">
Order Type
<InfoTooltip content="BD = Business Development (pre-sales), CHARGEABLE = billable client work, INTERNAL = internal project, OVERHEAD = non-project overhead." />
</label>
<select
id="orderType"
@@ -348,6 +352,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="allocationType">
Allocation
<InfoTooltip content="INT = staffed with internal resources, EXT = staffed with external contractors or freelancers." />
</label>
<select
id="allocationType"
@@ -365,6 +370,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="winProbability">
Win Probability %
<InfoTooltip content="Likelihood of winning this project (0-100%). Affects the weighted pipeline value: budget x probability." />
</label>
<input
id="winProbability"
@@ -391,6 +397,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="utilizationCategoryId">
Utilization Category
<InfoTooltip content="Groups projects for chargeability and utilization reporting. Determines how hours count toward resource utilization." />
</label>
<select
id="utilizationCategoryId"
@@ -409,6 +416,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="clientId">
Client
<InfoTooltip content="The client or customer this project is for. Used for filtering and reporting." />
</label>
<select
id="clientId"
@@ -437,6 +445,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="startDate">
Start Date
<InfoTooltip content="First day of the project period. Assignments begin from this date." />
</label>
<DateInput
id="startDate"
@@ -451,6 +460,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="endDate">
End Date
<InfoTooltip content="Last day of the project period. Must be on or after the start date." />
</label>
<DateInput
id="endDate"
@@ -466,6 +476,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="budgetEur">
Budget ()
<InfoTooltip content="Total project budget in EUR. Tracked against the sum of assignment costs (hours x daily rate)." />
</label>
<input
id="budgetEur"
@@ -493,6 +504,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="status">
Status
<InfoTooltip content="DRAFT = not visible on timeline, ACTIVE = in progress, ON_HOLD = paused, COMPLETED = finished, CANCELLED = abandoned." />
</label>
<select
id="status"
@@ -510,6 +522,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="responsiblePerson">
Responsible Person
<InfoTooltip content="Project lead or account manager responsible for this project." />
</label>
<input
id="responsiblePerson"
@@ -523,6 +536,7 @@ export function ProjectModal({ project, onClose }: ProjectModalProps) {
<div>
<label className={labelClass} htmlFor="projectColor">
Timeline Color
<InfoTooltip content="Custom color for this project's bars on the timeline view. Leave empty for the default color." />
</label>
<div className="flex items-center gap-2">
<input