M19

Work — Opportunities, Proposals & Engagements

The full hiring funnel: post jobs, gigs, or contracts, review proposals through a five-stage pipeline, and hire into engagements with time cards and approvals. Configure it gig-first, contract-first, or job-first — one funnel, your vocabulary.

API workflow reference →
The shape of it

Opportunity → Proposal → Engagement.

Three concepts carry the whole module. A posting attracts bids, a bid moves through the pipeline, and an accepted bid becomes a live working relationship. Everything else — templates, time cards, approvals — hangs off one of these three.

A

Opportunity

The posting

A job, a gig, or a contract — with term type, exact compensation, location or remote, and public or private visibility.

  • Created from scratch, a template, or an AI draft
  • Published now or scheduled with Publish On
  • Draft → Published → Archived lifecycle
B

Proposal

The bid

One per party — individual or company — with amount, term, estimated hours, available start, and cover message.

  • Shortlist + favorite flags at grid level
  • Chat + video calls, one conversation each
  • Five pipeline stages, movement in any direction
C

Engagement

The live relationship

Created Pending at acceptance; goes Active the moment its M20 contract is fully executed. Owns its own terms from day one.

  • Terms copied at acceptance — never drift
  • Contract-gated activation, 90-day expiry
  • Time cards and approvals accrue here

The structural point: one opportunity spawns many engagements. Hiring ten people against one posting is one opportunity, ten proposals at Hired, and ten independent engagements — each with its own contract, terms, status, and time cards.

Posting

One form posts a job, a gig, or a contract.

Every field in one pass: posting type, public or private visibility, remote or located, term type with an exact compensation amount, target start date, and a Markdown description with an ideal-candidate background. Save as a draft or publish on the spot.

  • Posting type is chosen once — Job, Gig, or Contract — and the compensation suffix follows the term type: fixed amount, per month, per week, per day, per hour
  • Drafts don't need pricing — compensation is enforced at publish, not at save
  • Skills ride the platform's shared tagging system, so posting chips and search stay consistent site-wide
AI drafting

Describe the work; the posting writes itself.

Give the AI a rough description and get back a complete draft — title, description, ideal-candidate background, suggested skills. The draft round-trips through the API and lands in the normal posting form; nothing is persisted until you save.

  • The draft is fully editable — it fills the same form the manual path uses
  • Title, description, and ideal-candidate background come back sized to the posting's field limits
  • No orphaned records — abandon the draft and nothing was ever written
Scheduled publishing

Publish now, or at 9:00 AM your time.

Pick a future date, a time, and a timezone, and the posting sits at Publish On until the scheduled job fires. The stored UTC instant plus the poster's own timezone means an August 9:00 AM stays 9:00 AM — even across a daylight-saving boundary.

  • Publish On is a first-class posting status — the admin list shows exactly what's queued and for when
  • The schedule redisplays in the timezone the poster chose, and recomputes correctly if edited
  • A filtered index makes the publish sweep a cheap seek, not a scan of every posting ever created
Term types

Five term types price everything.

The most-reused lookup in the module: the same five terms price an engagement, frame a posting's compensation, type a time card, and set billing frequency. Learn it once, read it everywhere.

  • Fixed Bid
  • Monthly
  • Weekly
  • Daily
  • Hourly
The pipeline

Five stages, movement in any direction.

Proposals move New → Shortlisted → Advanced → Hired → Rejected — and back. Nothing enforces a direction; every transition records a reason, an actor, and an effective date, so the pipeline doubles as the audit trail.

  • New
  • Shortlisted
  • Advanced
  • Hired
  • Rejected

Work owns the hiring funnel end to end. A posting — a job, a gig, or a contract — attracts proposals; proposals move through a bidirectional five-stage pipeline; an accepted proposal becomes a live engagement; and that engagement accrues approved time ready to bill. The module is deliberately flexible: the same schema and screens run a gig marketplace, a contractor bench, or a traditional job board, because posting type, term type, and visibility are data, not code paths. The structural point that makes it scale: one opportunity spawns many engagements. Hiring ten people against one posting produces one opportunity, ten proposals at Hired, and ten independent engagements — each with its own contract, terms, status, time card, and approval flow. Contract execution is handled by M20 Contracts (an engagement stays Pending until its contract is fully executed), proposal chat and video calls run through M07 Messaging, attachments live in shared blob storage alongside M16, and skills tagging rides the platform's shared label system.

Capabilities

  • Three posting types — Job, Gig, and Contract — chosen once per posting; the module reads the same either way, so you can run it gig-focused, contract-focused, or job-focused
  • Posting lifecycle — Draft, Published, Publish On (scheduled), Archived, and Deleted; deleted postings stay visible to admins with full history and can be reopened
  • Scheduled publishing — pick a future date, time, and timezone and the posting sits at Publish On until a background job fires it; the stored UTC instant plus the poster's IANA zone keeps the schedule correct across DST boundaries
  • Term + compensation — five term types (Fixed Bid, Monthly, Weekly, Daily, Hourly) with a single exact compensation amount, suffixed per term in the UI
  • Location or remote — a remote flag plus country, state, city, and postal code for on-site work
  • Posting templates — reusable templates carry prefill for every field including localized title, description, and ideal-candidate background, track usage counts, and resolve one default per posting type plus one global default
  • AI drafting — describe the work and get a complete posting draft back; nothing persists until the user saves, and the draft lands in the normal posting form for editing
  • Proposals — one bid per party, individual or company, with bid amount, term, estimated hours, available start date, cover message, and attachments (résumés, portfolios, work samples)
  • Shortlist + favorite — two independent grid-level flags with actor and timestamp, filterable without opening a proposal
  • Bidirectional pipeline — New, Shortlisted, Advanced, Hired, Rejected; movement in any direction including back out of Rejected, every transition recorded with reason, actor, and effective date
  • Proposal chat + video — one conversation per proposal through M07 Messaging; chat, instant video, and scheduled calls share the thread
  • Engagements — one posting, many hires; terms are copied at acceptance so later edits to the posted rate never move an executed engagement
  • Contract-gated activation — an engagement starts Pending and only goes Active when its M20 contract is fully executed; declined, expired, or 90-day-stale pending engagements terminate automatically
  • Time cards — one card per billing period with per-entry hours, optional per-entry billable rate, automatic or manual approval, and a reviewer work queue; approved, unbilled entries roll up cleanly for billing

Benefits

  • One posting hires ten people without duplicated records — each engagement carries its own contract, terms, and time cards
  • Nothing goes live on a handshake — the engagement activates only when the contract is executed, and expires if it never is
  • The pipeline is an audit trail, not just a kanban — every move records who, why, and when, in both directions
  • The same module ships a gig marketplace, a contractor bench, or a job board — posting type and term type are configuration, not forks

Flow of work

  1. 01Post — create from scratch, from a template, or from an AI draft; publish now or schedule Publish On
  2. 02Review — proposals arrive one per party; shortlist, favorite, take notes, chat and video-call through M07
  3. 03Advance — move the pipeline in any direction; every transition records a reason
  4. 04Hire — accept a proposal; an engagement is created Pending with terms defaulted from the posting
  5. 05Execute — the M20 contract goes out; fully executed flips the engagement Active
  6. 06Track — time cards per billing period, automatic or manual approval, approved hours ready to bill

Subfeatures

  • Job / Gig / Contract posting types
  • Draft → Published lifecycle
  • Publish On scheduling (DST-safe)
  • Archive + reopen
  • Admin-visible soft delete
  • Exact compensation + five term types
  • Remote or located postings
  • Posting attachments
  • Pinned posting notes
  • Posting templates with prefill
  • Per-type + global default templates
  • Template usage counts
  • AI posting drafts
  • One proposal per party
  • Bid amount / term / estimated hours
  • Shortlist + favorite flags
  • Reviewer notes on proposals
  • Proposal attachments
  • Proposal chat + video via M07
  • Bidirectional five-stage pipeline
  • Status-change reasons + history
  • Engagement per accepted proposal
  • Terms copied at acceptance
  • Pending → Active gated on M20 contract
  • 90-day pending expiry
  • Pause / terminate / re-engage with reasons
  • Time card per billing period
  • Per-entry billable rate
  • Automatic or manual approval
  • Unapproved-entry work queue
Source surfaces (technical reference)

Internal code areas in the licensed Full-Stack codebase that back this module.

  • ApiWorkOpportunity — posting CRUD, publish, archive, reopen, AI draft
  • ApiWorkOpportunityTemplate — prefill payload, defaults, usage counts
  • ApiWorkProposal — bids, flags, status changes, conversation join
  • ApiWorkEngagement — lifecycle, status changes, notes
  • ApiWorkTimeCard — periods, entries, approval queue
  • Scheduled Publish On job + pending-expiry job
Feature matrix

Gig-focused vs. Contract-focused vs. Job-focused, side by side.

The same schema, the same screens, the same 49 endpoints — these are configuration choices, not code forks. Every posting picks its own type, so a gig marketplace can still publish the occasional job, and a contractor bench can run one-off gigs alongside its retainers.

ConfigurationGig-focusedContract-focusedJob-focused
Posting typeGigContractJob
Typical term typesFixed Bid · HourlyMonthly · Weekly · DailyMonthly, salary-style
Compensation reads asFixed amount, or per hourPer month / week / dayPer month
Default visibilityPublic — cast a wide netPrivate — invited partiesPublic or private
Proposal emphasisBid amount + portfolio samplesRate + estimated hours + start dateCover message + résumé
Pipeline usageFast — New straight to HiredFull five stagesFull five stages, interviews via chat + video
Hires per postingMany — one gig, many engagementsOne to a fewUsually one per seat
Time card approvalAutomaticManual reviewManual review
Engagement shapeShort, fixed-scopeOngoing until terminatedOngoing — pause and re-engage
M20 contract templateLightweight gig agreementMaster services agreementEmployment-style agreement
Contract-gated activation

No engagement goes live on a handshake.

Accepting a proposal creates the engagement at Pending, not Active. The contract — resolved from the posting's template, cloned, pre-filled, and sent through M20 Contracts — has to come back fully executed before the engagement activates. Declined, expired, or 90-day-stale contracts terminate the engagement and put the proposal back in the pipeline.

  • Terms are copied onto the engagement at acceptance — editing the posted rate later never moves an executed engagement
  • Activation, decline, and expiry transitions are system-authored with their own reason codes, so the history reads honestly
  • Ten hires against one posting means ten independent engagements — each with its own contract, terms, and time cards
In the stack

Where it lives. What it exposes.

A quick visual of how Work — Opportunities, Proposals & Engagements participates across the CleenUI stack, alongside the named operations it adds to the API surface.

M19 · architecture
Frontend
React · TailwindCSS · 60+ components
Posting form (full fields + AI draft)Template picker with live previewPublish On schedulerProposal review grid (shortlist / favorite filters)Pipeline board with reason dialogsEngagement detail (status, notes, terms)Time card entry + approval queue
API
C# Web API · production-ready · role-aware
Opportunity CRUD + publish / archive / reopenAI draft generationTemplate CRUD + default resolutionProposal CRUD + flags + status transitionsEngagement lifecycle + status historyTime card + entry save / submit / approve
Database
AzureSQL · 300+ tables · 700+ procedures
OpportunitiesOpportunityTemplatesOpportunityAttachmentsOpportunityNotesProposalsProposalStatusChangesProposalConversationsEngagementsEngagementStatusChangesTimeCardsTimeCardEntries
Async Services and Batch Jobs
WebJobs & Functions · queue-backed
Scheduled Publish On jobPending-engagement expiry sweepAutomatic approval stampingContract-execution status listener
All four layers ship together as the Full-Stack license. M19 blocks are highlighted.
API operations

Named operations on this surface

30
Try these in Postman
  • POSTJob / Gig / Contract posting types/work/job-gig-contract-posting-types
  • POSTDraft → Published lifecycle/work/draft-published-lifecycle
  • POSTPublish On scheduling (DST-safe)/work/publish-on-scheduling-dst-safe
  • POSTArchive + reopen/work/archive-reopen
  • POSTAdmin-visible soft delete/work/admin-visible-soft-delete
  • POSTExact compensation + five term types/work/exact-compensation-five-term-types
  • POSTRemote or located postings/work/remote-or-located-postings
  • POSTPosting attachments/work/posting-attachments
  • POSTPinned posting notes/work/pinned-posting-notes
  • POSTPosting templates with prefill/work/posting-templates-with-prefill
  • POSTPer-type + global default templates/work/per-type-global-default-templates
  • POSTTemplate usage counts/work/template-usage-counts
  • POSTAI posting drafts/work/ai-posting-drafts
  • POSTOne proposal per party/work/one-proposal-per-party
  • POSTBid amount / term / estimated hours/work/bid-amount-term-estimated-hours
  • POSTShortlist + favorite flags/work/shortlist-favorite-flags
  • POSTReviewer notes on proposals/work/reviewer-notes-on-proposals
  • POSTProposal attachments/work/proposal-attachments
  • POSTProposal chat + video via M07/work/proposal-chat-video-via-m07
  • POSTBidirectional five-stage pipeline/work/bidirectional-five-stage-pipeline
  • POSTStatus-change reasons + history/work/status-change-reasons-history
  • POSTEngagement per accepted proposal/work/engagement-per-accepted-proposal
  • POSTTerms copied at acceptance/work/terms-copied-at-acceptance
  • POSTPending → Active gated on M20 contract/work/pending-active-gated-on-m20-contract
  • POST90-day pending expiry/work/90-day-pending-expiry
  • POSTPause / terminate / re-engage with reasons/work/pause-terminate-re-engage-with-reasons
  • POSTTime card per billing period/work/time-card-per-billing-period
  • POSTPer-entry billable rate/work/per-entry-billable-rate
  • POSTAutomatic or manual approval/work/automatic-or-manual-approval
  • POSTUnapproved-entry work queue/work/unapproved-entry-work-queue

Each operation maps to an endpoint in the licensed C# Web API surface.