Console
The construction console on port 3508 — the project portfolio, a project's plan on a timeline, the document register, and the weekly report.
frontend/construction-app is a Flow MUI app following the frontend
skill. Its construction screens read one backend, construction-api on 8145, through
src/service/construction/.
./localenv up construction-app # http://localhost:3508Signing in
The console signs in the same way as the intelligence app. Deployed, it sits behind
Cloudflare Access: every request sends the CF_Authorization cookie, and the page
reloads when that cookie is missing or expired so Access can sign the person in again.
Locally there is no Access, so the app sends the X-Dev-Principal header with
DEV_PRINCIPAL (or DEV_ACTOR from the repository-root .env), and construction-api
runs with DEV_AUTH=1 to accept it.
Navigation
The navigation follows intelligence-app: workspaces, each with sections that fold away, each section with its pages. Click the workspace name in the top bar to switch.
| Workspace | Section | Pages |
|---|---|---|
| Planning | Projects | All projects, Master plans, Ground up, Conversions, Capital improvements, Timeline |
| Planning | Governance | Decisions, Approvals, Risks |
| Documents | Document control | Register |
| Reports | Portfolio | Weekly report |
| Vendors | Directory | Firms |
| Vendors | Compliance | Insurance |
| Parts Catalog | Catalog | All parts, Building parts, Furniture, Fixtures and finishes, Cleaning materials, Fabrication parts, Safety |
The tab, the chosen record, the filters and the page are all in the query string, so a pasted link reproduces the view.
The portfolio
All projects is the portfolio: the projects on the left, the chosen project on the right.
Each card shows the project's stage, its health (on track, at risk, off track, complete),
and whether this week's update is in (current, update due, stale), because the question
someone opens the portfolio with is which projects need attention. The list filters by
status, health, freshness and stage, and searches by name or code. Each type page is the
same list filtered by kind, and "Start a project" on it starts with that type chosen.
Timeline puts every project on one chart: the planned dates as a pale bar, the forecast drawn over it, and the next six weeks of milestones as markers. A project whose forecast runs past its baseline finish (or its planned finish, before award) is drawn late. Clicking a row opens the project.
A project
The chosen project has nine tabs. The header shows its stage and has two actions: "Post update" for the weekly update, and Advance.
| Tab | What it shows |
|---|---|
| Overview | Progress, health and freshness, the seven stages with the current one marked, what the project is waiting on, its packages, the next milestones, the latest update, and the top risks |
| Plan | The stages and their tasks on one timeline, then the packages, the task list, milestones, and baselines |
| Documents | The controlled documents linked to the project, each with its current published revision. A row opens the document in a drawer |
| Budget | Variations, budget lines with committed and actual cost, and the cost events |
| Activity | What changed on the project recently, newest first |
| Decisions | The decision register with cost and schedule in their own columns |
| Approvals | Stage gates with whether each is approved, then every other approval, with approve and reject on each pending row |
| Risks | The risk register, with status as a select because a risk moves between four states in no fixed order |
| Vendors | The firms on the project, their contacts, and their fees and invoices |
Counts on the overview are buttons. Each opens the tab listing what it counted, with the filter already set. A figure a reader cannot drill into is a figure they have to take on trust; the reasoning is on Measuring progress.
The plan
The timeline has one row per stage, with that stage's tasks nested under it. Planned dates are the pale bar and the forecast is drawn over it, so a row that runs late shows the overrun past the end of the plan. Colour is used only where it means something: late rows are drawn in the red accent, and everything else is the plain Flow palette. A vertical line marks today, and the zoom (weeks or months) is in the query string.
Clicking a task opens it in a drawer over the timeline, so the reader stays where they were. The drawer shows the task's dates, progress, owner, the projects it counts toward, what it depends on, the documents it requires, its notes, and its files. Marking a task done is refused while a task it depends on is unfinished, or while a document it requires has no published revision, and the refusal is shown under the form.
Advancing a stage
Advance moves the project to its next stage. From initiation, final product approval, tender and award it needs an approved stage gate; the Approvals tab requests one with the subject filled in. From award, Advance opens a form for the awarded firm (which has to be on the Vendors tab first), the contract value, the baseline budget, and the construction start and finish; passing it writes the first baseline. From closeout the button reads Complete instead.
A refused advance keeps its reason above the tab content rather than in a toast that fades, because the reason is usually "there is no approved gate" and the reader's next move is to go and look at the Approvals tab. The reason has to still be there when they get back.
Documents
Register lists every controlled document with its current published revision. By default it lists only documents that have one, because that is what people build from; working copies are one filter away. The list filters by type and discipline and searches by code or title.
A document shows its current published revision first. Reading a superseded revision shows a banner naming the revision that replaced it. Below that are:
- the revisions, newest first, with the next step for an internal revision as a button: send for review, mark reviewed, send for approval, approve, or reject
- Publish on an approved revision, which asks what the change affects: the projects and tasks, whether it changes cost or schedule, and whether it needs a variation. Asking for a variation drafts one on the project in the same step
- the trail of who prepared, reviewed and approved each revision, with their comments
- the files on the chosen revision, and the projects and stages the document is linked to
The same document detail opens from a project's Documents tab.
Budget and variations
The Budget tab lists the project's Variation: A change to the cost or schedule agreed at award, for example extra work a new drawing revision needs. It is approved through an approval, and incorporating it writes a new baseline.s first, because after award a variation is the only way the budget or finish date changes. Each step is a button on the variation's row: price it, send it for approval with named reviewers, and once that approval is approved, incorporate it, which writes a new baseline. Below the variations are the budget lines per category with what has been committed and spent against each, and the cost events those totals are summed from. A correction is a negative event.
Weekly report
Weekly report is the portfolio report, computed when the page opens and filtered by region. Each project row has its stage, health, whether the update is in, progress, forecast finish and how many days that is past the baseline, what has been spent, the next milestone, and the commentary from the update its manager posted this week. A project with no update this week says so, rather than repeating last week's note as if it were current. Under the projects is every open variation with its cost and time. Nothing is stored for the report and nothing is sent on a schedule yet.
Starting a project
The new-folder icon above the list, "Start a project", opens a form for a new project: its type, name, code, region, project manager, planned start and finish, approved budget, and the site's location id. The type is one of master plan, ground up, conversion, or capital improvement, and is fixed once the project exists. Every project gets the same seven stages and starts in initiation. The new project is selected once it is created.
The site is entered as the site's id in the locations service, because the console does not read the locations service yet.
Vendors and the parts catalog
Firms is the directory every project shares: a firm is added once, its people are added
there so they can sign in to the vendor portal, and it is then put on each project from
that project's Vendors tab. A firm's page lists its people, the insurance it holds now,
and every project it has been on; certificates of insurance are recorded there.
Insurance lists every active firm's latest certificate for each kind of insurance,
soonest expiry first, filtered by status (current, expiring within 30 days, expired) and
by coverage. The Vendors workspace reads the
vendors service on port 8146 (VENDORS_SERVICE_URL);
a firm's projects come from construction-api.
Parts Catalog is a demo. It lists the parts, furniture, and supplies that could be ordered
for a project as a product listing: filters for type, availability, price band, and
brand on the left, a grid of parts on the right, and each part's specs in a dialog. Each
category page is the same listing limited to one category. There is no catalog API yet;
the parts are mock data in src/service/catalog/, filtered in the browser.
Refusals are shown, not prevented
The console offers Approve and Reject on every pending approval, Advance on every active
project, and Done on every open task. It does not try to work out in the browser whether
the caller is an editor, a named reviewer, or whether a gate or a document is in place.
A caller who is not in CONSTRUCTION_EDITORS sees the same buttons and gets the API's
403 message. Every form shows a refusal from the API under the form, so the field can be
corrected, and a toast confirms the change once it goes through.
Verify it
From frontend/construction-app:
pnpm lint
pnpm buildRun those from the app directory, not with pnpm --dir from the repository root: the
frontends pin different pnpm versions and corepack resolves that from the working
directory.