Grow a real OKR company: officers, departments, ranks - and a stable chart
Researched how OKR-run companies cascade (company objective -> C-suite officers per function -> department objectives -> individual key results) and encoded that shape into how the CEO builds the org. - hire_agent gains seniority (director/lead/staff; c_suite stays reserved for the CEO's privileges) and a business-card title, so the CEO hires a CTO/CFO/CMO as directors instead of a flat pool of ICs - CEO persona + goal kickoff now direct the OKR cascade: hire 2-4 officers, hand each a department objective, let them build teams; department heads get their own doctrine (hire leads/staff, cascade key results as tasks, report up) - Migration 050 adds Finance and Sales to every org's canonical departments (backfilled for existing DBs) so a real C-suite has somewhere to hire - Org chart viewport is a fixed-height scroll region: zooming rescales the diagram inside it instead of resizing the card - Unit test drives a live three-level chain: CEO -> CTO (director) -> Engineering Manager (lead) -> staff, with rank/title persisted
This commit is contained in:
1 parent
c3924af9ac
commit
2bb2acd635
9 files changed
+125
-10
No files matched your search
@@ -0,0 +1,24 @@
|
||||
export const financeSalesDepartmentsSchema = `
|
||||
insert into org_departments(id, org_id, name, lead_agent_id, headcount_limit, monthly_budget_limit_cents, created_at, updated_at)
|
||||
select 'dep_fin_' || o.id, o.id, 'Finance', null, 12, 2500000, datetime('now'), datetime('now')
|
||||
from organizations o
|
||||
where not exists (select 1 from org_departments d where d.org_id = o.id and lower(d.name) = 'finance');
|
||||
|
||||
insert into org_departments(id, org_id, name, lead_agent_id, headcount_limit, monthly_budget_limit_cents, created_at, updated_at)
|
||||
select 'dep_sal_' || o.id, o.id, 'Sales', null, 12, 2500000, datetime('now'), datetime('now')
|
||||
from organizations o
|
||||
where not exists (select 1 from org_departments d where d.org_id = o.id and lower(d.name) = 'sales');
|
||||
|
||||
insert into hiring_policies(id, org_id, department_name, max_headcount, monthly_budget_limit_cents, require_approval_above_cents, created_at, updated_at)
|
||||
select 'hpl_fin_' || o.id, o.id, 'Finance', 12, 2500000, 500000, datetime('now'), datetime('now')
|
||||
from organizations o
|
||||
where not exists (select 1 from hiring_policies hp where hp.org_id = o.id and lower(hp.department_name) = 'finance');
|
||||
|
||||
insert into hiring_policies(id, org_id, department_name, max_headcount, monthly_budget_limit_cents, require_approval_above_cents, created_at, updated_at)
|
||||
select 'hpl_sal_' || o.id, o.id, 'Sales', 12, 2500000, 500000, datetime('now'), datetime('now')
|
||||
from organizations o
|
||||
where not exists (select 1 from hiring_policies hp where hp.org_id = o.id and lower(hp.department_name) = 'sales');
|
||||
|
||||
insert into schema_migrations(version, name, applied_at)
|
||||
values (50, 'finance_sales_departments', datetime('now'));
|
||||
`;
|
||||
@@ -48,6 +48,7 @@ import { composioKeyPurgeSchema } from "./migrations/046-composio-key-purge";
|
||||
import { authConfigPurgeSchema } from "./migrations/047-auth-config-purge";
|
||||
import { uiPreferencesSchema } from "./migrations/048-ui-preferences";
|
||||
import { avatarsSchema } from "./migrations/049-avatars";
|
||||
import { financeSalesDepartmentsSchema } from "./migrations/050-finance-sales-departments";
|
||||
|
||||
interface Migration {
|
||||
version: number;
|
||||
@@ -105,6 +106,7 @@ const MIGRATIONS: Migration[] = [
|
||||
{ version: 47, name: "auth_config_purge", sql: authConfigPurgeSchema },
|
||||
{ version: 48, name: "ui_preferences", sql: uiPreferencesSchema },
|
||||
{ version: 49, name: "avatars", sql: avatarsSchema },
|
||||
{ version: 50, name: "finance_sales_departments", sql: financeSalesDepartmentsSchema },
|
||||
];
|
||||
|
||||
const SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1].version;
|
||||
|
||||
Reference in new issue
Block a user