| 1 | /** |
| 2 | * What a project will have and does not yet: the pages the project menu |
| 3 | * shows as Soon, each with a page of its own saying what it will be. One |
| 4 | * place, so the menu and those pages never disagree. |
| 5 | * |
| 6 | * Each entry says what it is for, what it will do, and what to use today, |
| 7 | * so a Soon is a promise someone can read, not a greyed-out word. |
| 8 | */ |
| 9 | |
| 10 | export type RoadmapItem = { |
| 11 | /** In the address: `/<owner>/<project>/soon/<key>`. */ |
| 12 | key: string; |
| 13 | title: string; |
| 14 | /** |
| 15 | * Where it lives: a project page whose tabs it joins, a page of its own |
| 16 | * in the project's sidebar ("Project"), or the workspace, for what spans |
| 17 | * projects (Insights). |
| 18 | */ |
| 19 | section: "Code" | "Issues" | "Deployments" | "Observability" | "Security" | "Insights" | "Project" | "Workspace"; |
| 20 | /** One line, for the menu's tooltip and the page's lead. */ |
| 21 | summary: string; |
| 22 | /** Why it matters, in two or three sentences. */ |
| 23 | why: string; |
| 24 | /** What it will do. */ |
| 25 | plans: string[]; |
| 26 | /** What to use until it exists: a project page, by its path under the project. */ |
| 27 | today?: { label: string; path: string }; |
| 28 | }; |
| 29 | |
| 30 | export const ROADMAP: RoadmapItem[] = [ |
| 31 | // --- Workspace ---------------------------------------------------------- |
| 32 | { |
| 33 | key: "insights", |
| 34 | title: "Insights", |
| 35 | section: "Workspace", |
| 36 | summary: "How the whole workspace delivers: lead time, reviews and what it costs, across every project.", |
| 37 | why: "Each project will have its own numbers. The workspace's put them side by side, so you can see which projects ship steadily, where work waits, and where the money goes.", |
| 38 | plans: [ |
| 39 | "Delivery metrics for every project, side by side", |
| 40 | "Where work waits: review, the merge queue, checks", |
| 41 | "Cost by project, by kind of work and per merged change", |
| 42 | ], |
| 43 | }, |
| 44 | // --- Code --------------------------------------------------------------- |
| 45 | // Nothing: code is not docs. Docs is its own workspace mode, filterable |
| 46 | // by project there, and a project never gets a Docs tab. |
| 47 | |
| 48 | // --- Deployments ---------------------------------------------------------- |
| 49 | { |
| 50 | key: "environments", |
| 51 | title: "Environments", |
| 52 | section: "Deployments", |
| 53 | summary: "Staging, production and others, with approvers and branch rules.", |
| 54 | why: "Production and previews exist today. Environments add the rest: staging, QA, per-customer, each with its own variables, approvers and rules for what may deploy there.", |
| 55 | plans: [ |
| 56 | "Named environments with their own variables and secrets", |
| 57 | "Required approvers before a deploy", |
| 58 | "Branch rules: what may deploy where", |
| 59 | "Promote a deployment from one environment to the next", |
| 60 | ], |
| 61 | today: { label: "Deployments", path: "deployments" }, |
| 62 | }, |
| 63 | |
| 64 | // --- Pages of their own in the project's sidebar ---------------------- |
| 65 | { |
| 66 | key: "analytics", |
| 67 | title: "Analytics", |
| 68 | section: "Project", |
| 69 | summary: "Who visits the deployed apps, without cookies.", |
| 70 | why: "Visits, pages and referrers for each app, private by design, from Cloudflare's own analytics.", |
| 71 | plans: ["Visits, pages, referrers and countries", "No cookies, no personal data", "Per deployment and per preview"], |
| 72 | }, |
| 73 | { |
| 74 | key: "firewall", |
| 75 | title: "Firewall", |
| 76 | section: "Project", |
| 77 | summary: "Rules for who may reach the project's deployed apps.", |
| 78 | why: "Deployed apps run on Cloudflare. Rate limits, bot protection and IP rules, per app and environment.", |
| 79 | plans: ["Rate limits and bot protection", "IP and country rules", "Password-protected previews"], |
| 80 | today: { label: "Deployments", path: "deployments" }, |
| 81 | }, |
| 82 | { |
| 83 | key: "flags", |
| 84 | title: "Flags", |
| 85 | section: "Project", |
| 86 | summary: "Turn features on per environment or per user, without a deploy.", |
| 87 | why: "Ship code dark and turn it on when ready, for some users first, at the edge, with no deploy.", |
| 88 | plans: ["Flags read at the edge by deployed apps", "Rollouts by percentage, user or environment", "Reminders to clean up flags once fully on"], |
| 89 | today: { label: "Deployments", path: "deployments" }, |
| 90 | }, |
| 91 | |
| 92 | // --- Security ------------------------------------------------------------- |
| 93 | // The overview, secret scanning, code scanning, vulnerabilities and the |
| 94 | // dependency graph are built: see routes/repo/security-*.tsx. |
| 95 | |
| 96 | // --- Observe ------------------------------------------------------------ |
| 97 | { |
| 98 | key: "uptime", |
| 99 | title: "Uptime", |
| 100 | section: "Observability", |
| 101 | summary: "Checks that the app answers, from around the world.", |
| 102 | why: "Know the app is down before your users tell you, and who was told.", |
| 103 | plans: ["Checks from many places", "Alerts by email and webhook", "A public status page"], |
| 104 | }, |
| 105 | |
| 106 | // --- Insights ------------------------------------------------------------- |
| 107 | { |
| 108 | key: "delivery", |
| 109 | title: "Delivery", |
| 110 | section: "Insights", |
| 111 | summary: "Lead time, deploy frequency, change failure rate and time to restore.", |
| 112 | why: "The four numbers that say how well a team ships, measured from what actually happened in g1t.", |
| 113 | plans: ["DORA metrics from merges and deployments", "Review and queue time", "Trends by week and by project"], |
| 114 | }, |
| 115 | { |
| 116 | key: "costs", |
| 117 | title: "Costs", |
| 118 | section: "Insights", |
| 119 | summary: "What the project costs, by workflow run, sandbox, build and app.", |
| 120 | why: "Usage is charged by the workspace; here it is broken down for one project, so you can see what each part of the work costs.", |
| 121 | plans: ["Cost by kind of work and by issue", "Cost per merged change", "Budgets per project"], |
| 122 | }, |
| 123 | ]; |
| 124 | |
| 125 | export function roadmapItem(key: string): RoadmapItem | undefined { |
| 126 | return ROADMAP.find((item) => item.key === key); |
| 127 | } |
| 128 | |
| 129 | export function roadmapIn(section: RoadmapItem["section"]): RoadmapItem[] { |
| 130 | return ROADMAP.filter((item) => item.section === section); |
| 131 | } |