Project Schema
Felder
Project Schema
Schema for validating project entities
title
Project title
description
Project description
status
Project status
PLANNEDACTIVEIN_REVIEWON_HOLDCOMPLETEDCANCELLEDstartDate
Project start date (YYYY-MM-DD)
endDate
Project end date (YYYY-MM-DD)
budget
Project budget as decimal string
managerId
Project manager user UUID
orgUnitId
Organisational unit (department / team) the project is organisationally located in.
teamUserIds
Internal users that make up the project team (independent of orgUnitId). Used for team_member data scope, task filters and notifications.
partyId
Associated party UUID
partyAddressId
Specific site/address of the associated party
contractId
Associated contract UUID
standaloneBilling
ADR 0274 — STANDALONE billing for this project. When enabled, all billable time of this project (direct PROJECT bookings + its tickets + its tasks) is carved out of the customer collective Leistungsnachweis and billed as its own project LN via POST /projects/:id/generate-performance-record. NEW projects default to enabled=true (materialised at create). EXISTING projects with this object ABSENT are treated as collective (resolveBillingUnit: absent → not standalone) — production-safe, no backfill. `performanceRecord*`/`invoicedAt` back-references are server-set only.
enabled
performanceRecordId
performanceRecordNumber
invoicedAt
budgetMinutes
Time budget in minutes
budgetUsedMinutes
Used time budget in minutes (auto-computed)
methodology
Project methodology
KANBANSCRUMWATERFALLHYBRIDdefaultBoardId
Default board UUID
tags
Project tags
salesOrderId
Linked sales_order UUID (works for both native and weclapp-sourced orders). Phase 1 of ADR 0139.
salesOrderSource
Origin of the linked sales-order (ADR 0139)
internalweclappnullcontrolling
Aggregated controlling data for the project (ADR 0139). Recomputed by reconcile-order-tasks job and on task/time-record mutations.
totalPlannedMinutes
totalPlannedAmount
totalLoggedMinutes
totalLoggedAmount
totalBillableMinutes
totalBillableAmount
lastRecalculatedAt
weclappSalesOrderId
weclapp sales order ID
weclappOrderUrl
URL to the weclapp sales order detail page
weclappSalesOrderNumber
weclapp sales order number (e.g. AB-2026-00042)
weclappPerformanceRecordId
weclapp performance record created from the sales order at project billing completion (ADR 0412). Set once — the completion endpoint is idempotent on it.
weclappPerformanceRecordNumber
Number of the weclapp performance record (display/deep-link).
weclappBillingCompletedAt
When the weclapp billing completion ran for this project.
weclappSalesInvoiceId
weclapp sales invoice created from the performance record (ADR 0412). Set once — the create-invoice endpoint is idempotent on it.
weclappSalesInvoiceNumber
Number of the weclapp sales invoice (display).
weclappSalesInvoiceUrl
URL to the weclapp sales invoice detail page.
weclappInvoiceCreatedAt
When the weclapp sales invoice was created from the billing dialog.
weclappSalesOrderData
Cached weclapp sales order data
limits
Project cap configuration (budget, hours, deadlines). Used by /projects/:id/limits and warning logic.
budgetWarningPercent
Percent of budget at which a warning is raised
hoursWarningPercent
Percent of project-total hours at which a warning is raised
hoursPerTaskWarningPercent
Percent of task.maxMinutes at which a warning is raised
deadlineWarningDays
Days before the project deadline at which a warning is raised
hardBlockOnExceed
If true, new time records are rejected once project-level budget or hours are exceeded
thresholdsNotified
Threshold keys that have already triggered a notification (first-time only).
budgetCapPercent
Per-project HARD CAP (Obergrenze) as % of the € budget (controlling.totalLoggedAmount / budget). Once logged spend reaches this percent, further time bookings on the project or its tasks are rejected (422 project-cap-exceeded). null/absent ⇒ inherit the tenant default (settings.projects.defaultLimits.budgetCapPercent); 0 ⇒ explicitly no €-cap for this project (overrides a tenant default). Values > 100 allow a controlled overrun. Tolerated missing on existing projects — runtime fallback, no backfill.
hoursCapPercent
Per-project HARD CAP (Obergrenze) as % of the hours budget (usedMinutes / budgetMinutes). Once the projected usage reaches this percent, further time bookings are rejected (422). null/absent ⇒ inherit the tenant default (settings.projects.defaultLimits.hoursCapPercent), else the legacy limits.hardBlockOnExceed flag (= 100%); 0 ⇒ explicitly no hours-cap. Values > 100 allow a controlled overrun. Runtime fallback, no backfill.
lockThresholdPercent
Per-project override (%) for the task-progress review lock. When task completion (done/total) first reaches this, the project auto-locks for team-lead review. Null ⇒ use tenant default (settings.projectLock.thresholdPercent, default 70).
budgetLockThresholdPercent
Per-project override (%) for the BUDGET-progress review lock (ADR 0191). When budget usage (controlling.totalLoggedAmount / budget €) first reaches this, the project auto-locks for team-lead review — independent of, and OR-combined with, the task-progress lock. Setting a value enables budget-locking for this project even if the tenant default is off. Null ⇒ use tenant default (settings.projectLock.lockOnBudget + budgetThresholdPercent).
planLockThresholdPercent
Per-project override (%) for the POSITION-PLAN review lock (ADR 0422). When plan usage (controlling.totalLoggedMinutes / totalPlannedMinutes, else the amount equivalent) first reaches this, the project auto-locks for team-lead review — independent of, and OR-combined with, the task and budget locks. Exists because order-materialised projects usually carry no project-level €/hours budget: their planned effort lives in the position limits, so neither of the other two triggers can ever fire there. Setting a value enables plan-locking for this project even if the tenant switch is off. Null ⇒ use tenant default (settings.projectLock.lockOnPlan + planThresholdPercent).
reviewLock
Progress-based review lock state (ADR 0191). One-time checkpoint: once released it does not re-lock at the same threshold. Set/cleared ONLY by the project-lock service and the /projects/:id/review endpoints — listed in protectedFields so generic CRUD PATCH cannot write it.
status
none = never locked; locked = awaiting team-lead release (blocks technician time bookings); released = reviewed & freed (no re-lock at this threshold).
nonelockedreleasedthresholdPercent
Effective threshold (%) that triggered the lock.
lockedAt
lockedProgressPercent
Progress percent of the triggering metric (see lockedMetric) at the moment the lock fired.
lockedMetric
Which metric crossed its threshold and triggered the lock: "tasks" (completion done/total), "budget" (controlling.totalLoggedAmount / budget €) or "plan" (controlling.totalLoggedMinutes / totalPlannedMinutes — the position plan, ADR 0422). Drives the banner + review-task wording.
tasksbudgetplanconsumedMetrics
Per-metric one-time checkpoints already consumed (ADR 0191, extended by ADR 0422). A metric in this list does not re-lock — but the task, budget and plan checkpoints are independent, so releasing one never disables the others. Absent on locks written before this field existed; the service then derives it from lockedMetric (no backfill).
reviewTaskId
The auto-created review task assigned to the reviewer(s).
reviewerIds
Internal user IDs allowed to release (team leads of orgUnit, else the project manager). Mirrored onto the review task assignees.
releasedAt
releasedBy
Internal user ID who released the lock.
customerAccess
Customer access configuration for project visibility
mode
Access mode for customer project view
DISABLEDAUTHENTICATEDSECURE_LINKLINK_PLUS_LOGINvisibilityProfile
Predefined visibility profile or CUSTOM for manual feature selection
MINIMALSTANDARDEXTENDEDCOLLABORATIVECUSTOMaccessToken
Random token for public access URL
accessTokenCreatedAt
When the access token was generated
allowedPartyIds
Party UUIDs that are allowed to access the project
sourceTemplateId
task_template this project was instantiated from.
sourceTemplateVersion
Pinned template version at instantiation time.
inboundReplyAckedAt
Timestamp at which the latest inbound customer email was acknowledged as "handled, no reply needed". Clears the awaiting-reply badge when >= the last inbound email time; a newer inbound email re-arms it. Mirrors opportunity.inboundReplyAckedAt.
inboundReplyAckedBy
User who acknowledged the latest inbound customer email (see inboundReplyAckedAt).
Keine Felder passen zum Filter.
Standard-Endpoints
Diese Resource folgt dem generischen CRUD-Vertrag der Plattform. Lesen Sie die Konventionen für Pagination, Idempotenz, Optimistic Locking und Audit. Die wichtigsten Endpoints:
GET /api/v1/projects— Liste, paginiert + filterbarGET /api/v1/projects/<id>— Einzelne EntityPOST /api/v1/projects— AnlegenPATCH /api/v1/projects/<id>— Teil-UpdateDELETE /api/v1/projects/<id>— Soft-DeleteGET /api/v1/projects/<id>/timeline— Audit + Aktivitäten