Skip to content

Proposal Tools

Proposals model prospective work before it exists as a project — staffing lines, vendor commitments, live costing against a target efficiency ratio, and a capacity simulation for whether the team can actually take the work on. A proposal never touches operational reporting: it's excluded from every dashboard, forecast, and reminder VERA sends. It becomes real only when it's converted to a project, which is the first moment it appears anywhere else.

All proposal tools are Owner/Admin only and console-only — not reachable from Slack; use the web console.


create_proposal

Start a new proposal.

Console-only — not reachable from Slack; use the web console.

Writes to: proposals

Parameters:

ParamRequiredDescription
requesting_user_slack_id
name
prospect_nameThe prospective client's name
project_type"T&M" | "Fixed Price" | "Pro Bono" | "Internal" — defaults to "Fixed Price"
contract_value
target_lerTarget labor efficiency ratio for this proposal; falls back to the tenant's standard target when omitted
hours_budget
deadlineYYYY-MM-DD
notes

New proposals start as draft. A proposal is created and edited entirely apart from VERA's operational data — nothing here is joined into any project, financial, or capacity report until it's converted.


list_proposals

List proposals.

Reads from: proposals

Parameters:

ParamDescription
requesting_user_slack_id
statusOptional filter: "draft" | "won" | "lost" | "converted"

update_proposal

Update one or more fields on a proposal.

Console-only — not reachable from Slack; use the web console.

Updates: proposals

Parameters: requesting_user_slack_id, id, and any of name, prospect_name, project_type, contract_value, target_ler, hours_budget, status, notes, deadline

A proposal that is closedstatus is "won" or "lost", or it has already been converted to a project — can no longer be edited.


delete_proposal

Permanently delete a proposal. Proposals are speculative, so this is a hard delete, not an archive.

Console-only — not reachable from Slack; use the web console.

Deletes from: proposals

Parameters: requesting_user_slack_id, id

A proposal that has already been converted to a project cannot be deleted — once real work exists downstream of it, the proposal record stays as the paper trail.


create_proposal_role

Add a staffing line to a proposal — a discipline and/or a specific person, with planned hours and (for T&M) a proposed billing rate.

Console-only — not reachable from Slack; use the web console.

Writes to: proposal staffing lines

Parameters:

ParamRequiredDescription
requesting_user_slack_id
proposal_id
discipline_id
user_idA specific person, if the line is pinned to one
planned_hours
billing_rateFor T&M proposals
task
start_dateStaffing-line window start, YYYY-MM-DD. Both-or-neither with end_date.
end_dateStaffing-line window end, YYYY-MM-DD.
week_hoursHow the line's planned hours land across the weeks of its window — array of { week, hours }. Requires a window; the sum can't exceed planned_hours.

Costing precedence for an unrated line follows the same order get_proposal_costing uses: the pinned person's own rate, then the discipline's blended rate, then the agency's blended rate.


update_proposal_role

Update a staffing line.

Console-only — not reachable from Slack; use the web console.

Updates: proposal staffing lines

Parameters: requesting_user_slack_id, id, and any of discipline_id, user_id, planned_hours, billing_rate, task

Window and shape (presence-based, same rules as an allocation envelope): start_date/end_date are both-or-neither — omit both to leave the window untouched, send both to set or replace it, send both empty to clear it. week_hours is presence-based too — omitted leaves the shape untouched, an empty array clears it, a non-empty array is validated (every week a Monday inside the window, sum capped at planned_hours) and written. week_hours requires the line to already have a window.

Refused on a closed proposal (status won, lost, or already converted).


delete_proposal_role

Remove a staffing line from a proposal.

Console-only — not reachable from Slack; use the web console.

Deletes from: proposal staffing lines

Parameters: requesting_user_slack_id, id

Refused on a closed proposal.


create_proposal_liability

Add a vendor commitment to a proposal — a fixed-fee line for work the agency plans to outsource rather than staff internally.

Console-only — not reachable from Slack; use the web console.

Writes to: proposal vendor commitments

Parameters:

ParamRequiredDescription
requesting_user_slack_id
proposal_id
vendor_user_idMust be an existing user with the vendor employment type
description
agreed_amountPositive number
agreed_hours

The vendor must already exist as a user before it can be committed on a proposal — a new vendor is onboarded on the Users page first.

Refused on a closed proposal.


update_proposal_liability

Update a vendor commitment on a proposal.

Console-only — not reachable from Slack; use the web console.

Updates: proposal vendor commitments

Parameters: requesting_user_slack_id, id, and any of vendor_user_id, description, agreed_amount, agreed_hours

Refused on a closed proposal.


delete_proposal_liability

Remove a vendor commitment from a proposal.

Console-only — not reachable from Slack; use the web console.

Deletes from: proposal vendor commitments

Parameters: requesting_user_slack_id, id

Refused on a closed proposal.


get_proposal_costing

Live costing snapshot for a proposal — every staffing line and vendor commitment, each cost-rated, plus the resulting P&L.

Reads from: proposals, proposal staffing lines, proposal vendor commitments

Parameters: requesting_user_slack_id, proposal_id

Returns: the proposal; each staffing line annotated with its resolved cost_rate and rate_source ("person" | "discipline" | "agency"); the vendor commitments; and a pnl object with revenue, cost, profit, ler, margin_pct, target_ler, people_budget (revenue ÷ target LER), over_budget, total_hours, committed_envelope, committed_liability, and vendor_hours.

Revenue is the sum of each staffing line's hours × its proposed billing rate for a T&M proposal, or the proposal's contract value otherwise (Pro Bono and Internal naturally price at $0). This is a read-only computation — nothing here writes anything.