feat: implement governed project portfolio
This commit is contained in:
@@ -3,9 +3,13 @@
|
||||
## Owns
|
||||
|
||||
- portfolio and project identity
|
||||
- goals, status, dates, milestones, and project structure
|
||||
- versioned goals, intended outcomes, benefits, status, dates, milestones, and
|
||||
project structure
|
||||
- portfolio dependencies, capacity assumptions, change impact, and benefit
|
||||
review
|
||||
- participant and responsibility references
|
||||
- links to tasks, tickets, cases, files, Wiki pages, and calendar objects
|
||||
- links to mandates, services, risks, controls, contracts, grants, resources,
|
||||
indicators, tasks, tickets, cases, files, Wiki pages, and calendar objects
|
||||
- project-level external references and synchronization provenance
|
||||
|
||||
## Does Not Own
|
||||
@@ -15,6 +19,8 @@
|
||||
- file storage or Wiki content
|
||||
- workflow runtime
|
||||
- OpenProject transport, credentials, or synchronization jobs
|
||||
- policy decisions, risk/control lifecycle, resource booking, contract/grant
|
||||
obligations, or report calculation
|
||||
|
||||
## OpenProject Boundary
|
||||
|
||||
@@ -24,8 +30,55 @@ mapping diagnostics, synchronization, and migration. A project may remain
|
||||
external-only, linked, partially synchronized, imported, or native according
|
||||
to the integration maturity level recorded on its external reference.
|
||||
|
||||
## First Slice
|
||||
## Runtime Contract
|
||||
|
||||
Implement project identity, status, milestones, participants, resource links,
|
||||
and canonical OpenProject reference mapping before implementing a full native
|
||||
work-package model.
|
||||
The implemented aggregate uses stable identities and immutable revisions for
|
||||
`portfolio`, `project`, and `milestone` objects. Writes require an expected
|
||||
revision, an idempotency key, an aware timestamp, and a change reason. The
|
||||
module records a durable module event in the same transaction and publishes a
|
||||
platform event after commit.
|
||||
|
||||
Current normalized membership grants make restricted-object filtering and
|
||||
authorization efficient while every historical revision retains the exact
|
||||
owner and membership snapshot. Tenant-visible objects require the read scope;
|
||||
restricted objects additionally require creator, owner, membership, or admin
|
||||
access. Search stores only bounded document data and always rechecks the source
|
||||
authorization before returning a result.
|
||||
|
||||
Parent rules are explicit: portfolios have no parent, projects may belong to a
|
||||
portfolio, and milestones belong to a project. State changes use a per-kind
|
||||
transition map. Physical deletion is deliberately absent from the object API;
|
||||
cancelled/completed lifecycle state and governed module retirement preserve the
|
||||
audit trail.
|
||||
|
||||
## User And Admin Operation
|
||||
|
||||
Users work in `/projects`, where they can search and filter the planning
|
||||
catalogue, inspect outcome/governance summaries, and create or edit core
|
||||
planning fields. The API record additionally accepts first-class outcomes,
|
||||
benefits, dependencies, capacity assumptions, change impacts, benefit reviews,
|
||||
resource links, memberships, and external references. Administrators grant the
|
||||
Projects role templates and use ordinary module activation/migration controls;
|
||||
there is no Projects-specific credential or transport configuration.
|
||||
|
||||
Use Reporting for measured indicators and Risk Compliance for risks and
|
||||
controls; Projects retains planning intent and links. Use Tasks or Tickets for
|
||||
actionable work. A canonical OpenProject reference may use any declared
|
||||
integration maturity, but Connectors owns discovery, credentials, mapping,
|
||||
synchronization, and migration.
|
||||
|
||||
## Recovery And Limits
|
||||
|
||||
Database backup and restore cover identities, immutable revisions, normalized
|
||||
memberships, and events as one logical state set. Replaying a successful write
|
||||
with its original idempotency key returns the recorded revision; reusing the
|
||||
key with another request is rejected. A stale expected revision is rejected
|
||||
without changing current state.
|
||||
|
||||
The first WebUI edits the common object fields. Advanced planning collections
|
||||
are fully validated and persisted through the API but still need specialized
|
||||
editors. OpenProject synchronization is future Connectors work. Projects does
|
||||
not implement a native work-package lifecycle.
|
||||
|
||||
Do not create a separate Goals module until another domain proves a reusable,
|
||||
independent goal lifecycle that Projects cannot own through references.
|
||||
|
||||
Reference in New Issue
Block a user