Product & operations
Plan next year’s offer together, one proposal at a time.
It started with…
Campus teams propose next year’s programmes. Management, operations, teaching and communications all need a say, and a clear view of whose turn it is.
So we built…
A guided, five-stage workflow. The proposal stays on the same record as each team reviews it, adds context and passes it on for approval and publication.
Take a look inside
Screen 1 of 6Catalogue overview
Search and filter programmes by campus, with visible field diagnostics.
What we set out to change
Keep every proposal traceable from the campus request to publication, with incomplete requests visible along the way.
How it is builtData model, code, controls and team ownership
The user journey
- 01
A campus proposes an existing or new offer.
- 02
Each responsible team reviews the same request through the staged workflow.
- 03
Communications publishes approved offers; the record keeps its discussion history.
Base structure
| Entity / table | Key fields | Relationships |
|---|---|---|
| Intakes | Current stage · deadlines · source intake | One intake → many promotion proposals |
| Promotions | Programme · site · validation status · publication flag · discussion log | A proposal is a promotion record from the start |
| Programmes & pathways | Programme status · pathway · formats | A proposed programme joins the common offer reference |
| Sites | Catalogue validators | Campus responsibility is configured in the data |
Technical implementation
- A single status field identifies the current workflow stage. Comments are accumulated as a dated journal.
- The planning assistant checks duplicate combinations and missing select options before creation. It does not copy source CRM identifiers or old counters.
- The “view as” diagnostic mode is read-only, with guards in both the controls and the write helpers.
Engineering decision
Keep partial failures visible at the write boundary
Adapted from catalogue batch updates: sequential batches, per-record outcomes and progress reporting. Support preview remains read-only; this illustration rechecks it before every batch. Earlier successful batches are not rolled back when a later batch fails. Failed IDs require review before replay, and the local preview guard does not replace Airtable permissions.
export async function updateCatalogue(table, updates, context, onProgress) { const savedIds = []; const failed = []; let processed = 0; for (let offset = 0; offset < updates.length; offset += 50) { // Recheck after awaits: the user may have entered support preview. if (context.isImpersonating()) { return { status: "stopped-read-only", savedIds, failed, processed }; } const permission = table.checkPermissionsForUpdateRecords(); if (!permission.hasPermission) { return { status: "stopped-permission", savedIds, failed, processed }; } const batch = updates.slice(offset, offset + 50); try { await table.updateRecordsAsync(batch); savedIds.push(...batch.map(row => row.id)); } catch (error) { // Keep the affected record IDs; never report the whole run as saved. for (const row of batch) { failed.push({ id: row.id, reason: "write-failed" }); } } processed += batch.length; onProgress?.({ processed, total: updates.length }); } return { status: failed.length ? "partial" : "saved", savedIds, failed, processed };}Adapted implementation excerpt
Controls and boundaries
- The extension’s workflow roles are usage rules; underlying Airtable access still needs to be configured.
- The comment journal is an application history, not a tamper-proof audit system.
Who can contribute
- Campus teams: submit and complete proposals in the guided interface.
- Builders: maintain programmes, pathways, validators and intake dates.
- Developers: extend the workflow while preserving its status model and write guards.
What supports this case
The catalogue, contextual guide and source code share the same approval circuit. The field diagnostic makes missing configuration visible to builders.