496 lines
15 KiB
TypeScript
496 lines
15 KiB
TypeScript
/**
|
|
* Social Media Campaign seed — "MycoFi Earth Launch" campaign
|
|
*
|
|
* Demonstrates the folk-social-post component with a realistic
|
|
* multi-platform product launch campaign connected by folk-arrows
|
|
* in an n8n-style "this then that" flow.
|
|
*
|
|
* Flow layout (left-to-right, with parallel branches):
|
|
*
|
|
* [Trigger] → [X Teaser] → [LinkedIn Thought] → [IG Carousel] ──┐
|
|
* ├→ [YT Video] → [X Launch] → [LinkedIn Ann.] ──┐
|
|
* │ ├→ [IG Reel] → [Threads] → [Bluesky]
|
|
* └───────────────────────────────────────────────┘
|
|
*/
|
|
|
|
import {
|
|
addShapes,
|
|
communityExists,
|
|
createCommunity,
|
|
getDocumentData,
|
|
loadCommunity,
|
|
} from "./community-store";
|
|
|
|
// ── Layout constants ────────────────────────────────────────────
|
|
const COL_WIDTH = 320;
|
|
const COL_GAP = 100;
|
|
const ROW_HEIGHT = 420;
|
|
const ROW_GAP = 60;
|
|
const START_X = 60;
|
|
const START_Y = 60;
|
|
const NODE_W = 300;
|
|
const NODE_H = 380;
|
|
|
|
function col(n: number): number {
|
|
return START_X + n * (COL_WIDTH + COL_GAP);
|
|
}
|
|
function row(n: number): number {
|
|
return START_Y + n * (ROW_HEIGHT + ROW_GAP);
|
|
}
|
|
|
|
// ── Campaign seed data ──────────────────────────────────────────
|
|
|
|
const CAMPAIGN_SHAPES: Record<string, unknown>[] = [
|
|
// ────────────────────────────────────────────────────────────
|
|
// TRIGGER NODE (campaign start)
|
|
// ────────────────────────────────────────────────────────────
|
|
{
|
|
id: "campaign-trigger",
|
|
type: "folk-workflow-block",
|
|
x: col(0),
|
|
y: row(0) + 100,
|
|
width: 220,
|
|
height: 140,
|
|
rotation: 0,
|
|
blockType: "trigger",
|
|
label: "Campaign Start",
|
|
inputs: [],
|
|
outputs: [{ name: "launch", type: "trigger" }],
|
|
},
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// PHASE 1: Pre-Launch Hype (Days -3 to -1)
|
|
// ────────────────────────────────────────────────────────────
|
|
{
|
|
id: "post-x-teaser",
|
|
type: "folk-social-post",
|
|
x: col(1),
|
|
y: row(0),
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "x",
|
|
postType: "thread",
|
|
stepNumber: 1,
|
|
content:
|
|
"Something is growing in the mycelium... \ud83c\udf44\n\nFor the past 2 years, we've been building the infrastructure for a regenerative economy.\n\nOn Feb 24, we reveal everything.\n\nA thread on why the old financial system is composting itself \ud83e\uddf5\ud83d\udc47",
|
|
mediaUrl: "",
|
|
mediaType: "",
|
|
scheduledAt: "2026-02-21T09:00:00",
|
|
status: "scheduled",
|
|
hashtags: ["MycoFi", "RegenFinance", "Web3", "ComingSoon"],
|
|
},
|
|
|
|
{
|
|
id: "post-linkedin-thought",
|
|
type: "folk-social-post",
|
|
x: col(2),
|
|
y: row(0),
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "linkedin",
|
|
postType: "article",
|
|
stepNumber: 2,
|
|
content:
|
|
"The regenerative finance movement isn't just about returns \u2014 it's about redesigning incentive structures from the ground up.\n\nIn this article, I break down why mycelial network theory offers the best model for decentralized economic coordination.\n\n3 key insights from 2 years of building MycoFi Earth...",
|
|
mediaUrl: "",
|
|
mediaType: "image",
|
|
scheduledAt: "2026-02-22T11:00:00",
|
|
status: "scheduled",
|
|
hashtags: ["RegenerativeFinance", "DeFi", "SystemsThinking", "Leadership"],
|
|
},
|
|
|
|
{
|
|
id: "post-ig-carousel",
|
|
type: "folk-social-post",
|
|
x: col(3),
|
|
y: row(0),
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "instagram",
|
|
postType: "carousel",
|
|
stepNumber: 3,
|
|
content:
|
|
"5 Ways Mycelium Networks Mirror the Future of Finance \ud83c\udf0d\ud83c\udf44\n\nSlide 1: The problem with extractive finance\nSlide 2: How mycelium redistributes nutrients\nSlide 3: Token-weighted funding circles\nSlide 4: Community governance that actually works\nSlide 5: Join the launch \u2014 Feb 24",
|
|
mediaUrl: "",
|
|
mediaType: "carousel",
|
|
scheduledAt: "2026-02-23T14:00:00",
|
|
status: "scheduled",
|
|
hashtags: [
|
|
"MycoFi",
|
|
"RegenerativeEconomy",
|
|
"Infographic",
|
|
"Web3Education",
|
|
],
|
|
},
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// PHASE 2: Launch Day (Day 0)
|
|
// ────────────────────────────────────────────────────────────
|
|
{
|
|
id: "post-yt-launch",
|
|
type: "folk-social-post",
|
|
x: col(4),
|
|
y: row(0) - 30,
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "youtube",
|
|
postType: "video",
|
|
stepNumber: 4,
|
|
content:
|
|
"MycoFi Earth \u2014 Official Launch Video\n\nThe regenerative economy starts here. Watch how mycelial intelligence is reshaping finance, governance, and community coordination.\n\nFeaturing interviews with 12 builders from the ecosystem.\n\n[18:42]",
|
|
mediaUrl: "",
|
|
mediaType: "video",
|
|
scheduledAt: "2026-02-24T10:00:00",
|
|
status: "draft",
|
|
hashtags: [
|
|
"MycoFiLaunch",
|
|
"RegenerativeFinance",
|
|
"Documentary",
|
|
"Web3",
|
|
],
|
|
},
|
|
|
|
{
|
|
id: "post-x-launch",
|
|
type: "folk-social-post",
|
|
x: col(5),
|
|
y: row(0) - 60,
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "x",
|
|
postType: "thread",
|
|
stepNumber: 5,
|
|
content:
|
|
"\ud83c\udf44 MycoFi Earth is LIVE \ud83c\udf44\n\nAfter 2 years of building, the regenerative finance platform is here.\n\nWhat is it?\n\u2022 Token-weighted funding circles\n\u2022 Mycelial governance (no whales)\n\u2022 Composting mechanism for failed proposals\n\u2022 100% on-chain, 100% community-owned\n\n\ud83d\udc47 Full breakdown thread",
|
|
mediaUrl: "",
|
|
mediaType: "image",
|
|
scheduledAt: "2026-02-24T10:15:00",
|
|
status: "draft",
|
|
hashtags: [
|
|
"MycoFi",
|
|
"Launch",
|
|
"RegenFinance",
|
|
"DeFi",
|
|
"DAO",
|
|
],
|
|
},
|
|
|
|
{
|
|
id: "post-linkedin-launch",
|
|
type: "folk-social-post",
|
|
x: col(6),
|
|
y: row(0) - 30,
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "linkedin",
|
|
postType: "text",
|
|
stepNumber: 6,
|
|
content:
|
|
"Today we're launching MycoFi Earth \u2014 a regenerative finance platform modeled on mycelial networks.\n\nWhy it matters for the future of organizational design:\n\n1. Composting mechanism: Failed proposals return resources to the network\n2. Nutrient routing: Funds flow to where they're needed most\n3. No single point of failure: True decentralization\n\nFull video + docs in comments \u2193",
|
|
mediaUrl: "",
|
|
mediaType: "image",
|
|
scheduledAt: "2026-02-24T11:00:00",
|
|
status: "draft",
|
|
hashtags: [
|
|
"Launch",
|
|
"RegenerativeFinance",
|
|
"Innovation",
|
|
"FutureOfWork",
|
|
],
|
|
},
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// PHASE 3: Post-Launch Amplification (Day +1)
|
|
// ────────────────────────────────────────────────────────────
|
|
{
|
|
id: "post-ig-reel",
|
|
type: "folk-social-post",
|
|
x: col(7),
|
|
y: row(0) - 30,
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "instagram",
|
|
postType: "reel",
|
|
stepNumber: 7,
|
|
content:
|
|
"60-second explainer: How MycoFi Earth works \ud83c\udf44\u2728\n\nVisual breakdown of the token flow from contributor \u2192 funding circle \u2192 project \u2192 compost.\n\nSet to lo-fi beats with mycelium time-lapse footage.\n\nCTA: Link in bio to join the first funding circle.",
|
|
mediaUrl: "",
|
|
mediaType: "video",
|
|
scheduledAt: "2026-02-25T12:00:00",
|
|
status: "draft",
|
|
hashtags: [
|
|
"MycoFi",
|
|
"RegenFinance",
|
|
"Explainer",
|
|
"Web3",
|
|
"Reels",
|
|
],
|
|
},
|
|
|
|
{
|
|
id: "post-threads-xpost",
|
|
type: "folk-social-post",
|
|
x: col(8),
|
|
y: row(0) - 60,
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "threads",
|
|
postType: "text",
|
|
stepNumber: 8,
|
|
content:
|
|
"We just launched MycoFi Earth and the response has been incredible \ud83c\udf1f\n\nThe idea is simple: what if finance worked like mycelium?\n\nMycelium doesn't hoard \u2014 it redistributes. MycoFi applies that logic to community funding.\n\nEarly access is open. Come grow with us \ud83c\udf31",
|
|
mediaUrl: "",
|
|
mediaType: "",
|
|
scheduledAt: "2026-02-25T14:00:00",
|
|
status: "draft",
|
|
hashtags: ["MycoFi", "RegenEconomy", "Community"],
|
|
},
|
|
|
|
{
|
|
id: "post-bluesky-launch",
|
|
type: "folk-social-post",
|
|
x: col(9),
|
|
y: row(0),
|
|
width: NODE_W,
|
|
height: NODE_H,
|
|
rotation: 0,
|
|
platform: "bluesky",
|
|
postType: "text",
|
|
stepNumber: 9,
|
|
content:
|
|
"MycoFi Earth just went live \ud83c\udf44\n\nIt's a regenerative finance platform where funding flows like nutrients through a mycelial network.\n\nNo VCs. No whales. Just communities funding what matters.\n\nmycofi.earth",
|
|
mediaUrl: "",
|
|
mediaType: "",
|
|
scheduledAt: "2026-02-25T15:00:00",
|
|
status: "draft",
|
|
hashtags: ["MycoFi", "RegenFinance", "Bluesky"],
|
|
},
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// CAMPAIGN SUMMARY NODE
|
|
// ────────────────────────────────────────────────────────────
|
|
{
|
|
id: "campaign-summary",
|
|
type: "folk-markdown",
|
|
x: col(0),
|
|
y: row(0) - 200,
|
|
width: 500,
|
|
height: 160,
|
|
rotation: 0,
|
|
content:
|
|
"# \ud83c\udf44 MycoFi Earth Launch Campaign\n\n**Duration:** Feb 21\u201325, 2026 (5 days)\n**Platforms:** X, LinkedIn, Instagram, YouTube, Threads, Bluesky\n**Posts:** 9 total across 3 phases\n\n| Phase | Days | Posts |\n|-------|------|-------|\n| Pre-Launch Hype | Day -3 to -1 | 3 posts |\n| Launch Day | Day 0 | 3 posts |\n| Amplification | Day +1 | 3 posts |",
|
|
},
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// PHASE LABELS (markdown notes as section headers)
|
|
// ────────────────────────────────────────────────────────────
|
|
{
|
|
id: "label-phase1",
|
|
type: "folk-markdown",
|
|
x: col(1),
|
|
y: row(0) - 55,
|
|
width: COL_WIDTH * 3 + COL_GAP * 2,
|
|
height: 36,
|
|
rotation: 0,
|
|
content:
|
|
"### \ud83d\udce3 Phase 1: Pre-Launch Hype (Feb 21\u201323)",
|
|
},
|
|
{
|
|
id: "label-phase2",
|
|
type: "folk-markdown",
|
|
x: col(4),
|
|
y: row(0) - 85,
|
|
width: COL_WIDTH * 3 + COL_GAP * 2,
|
|
height: 36,
|
|
rotation: 0,
|
|
content: "### \ud83d\ude80 Phase 2: Launch Day (Feb 24)",
|
|
},
|
|
{
|
|
id: "label-phase3",
|
|
type: "folk-markdown",
|
|
x: col(7),
|
|
y: row(0) - 85,
|
|
width: COL_WIDTH * 3 + COL_GAP * 2,
|
|
height: 36,
|
|
rotation: 0,
|
|
content:
|
|
"### \ud83d\udce1 Phase 3: Amplification (Feb 25)",
|
|
},
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// ARROWS (flow connections)
|
|
// ────────────────────────────────────────────────────────────
|
|
|
|
// Trigger → X Teaser
|
|
{
|
|
id: "arrow-trigger-to-teaser",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "campaign-trigger",
|
|
targetId: "post-x-teaser",
|
|
color: "#64748b",
|
|
},
|
|
|
|
// X Teaser → LinkedIn Thought Leadership
|
|
{
|
|
id: "arrow-teaser-to-linkedin",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-x-teaser",
|
|
targetId: "post-linkedin-thought",
|
|
color: "#0A66C2",
|
|
},
|
|
|
|
// LinkedIn Thought → IG Carousel
|
|
{
|
|
id: "arrow-linkedin-to-ig",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-linkedin-thought",
|
|
targetId: "post-ig-carousel",
|
|
color: "#E4405F",
|
|
},
|
|
|
|
// IG Carousel → YouTube Launch (phase transition)
|
|
{
|
|
id: "arrow-ig-to-yt",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-ig-carousel",
|
|
targetId: "post-yt-launch",
|
|
color: "#FF0000",
|
|
},
|
|
|
|
// YouTube → X Launch Thread
|
|
{
|
|
id: "arrow-yt-to-x-launch",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-yt-launch",
|
|
targetId: "post-x-launch",
|
|
color: "#000000",
|
|
},
|
|
|
|
// X Launch → LinkedIn Announcement
|
|
{
|
|
id: "arrow-x-to-linkedin-launch",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-x-launch",
|
|
targetId: "post-linkedin-launch",
|
|
color: "#0A66C2",
|
|
},
|
|
|
|
// LinkedIn Announcement → IG Reel (phase transition)
|
|
{
|
|
id: "arrow-linkedin-to-reel",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-linkedin-launch",
|
|
targetId: "post-ig-reel",
|
|
color: "#E4405F",
|
|
},
|
|
|
|
// IG Reel → Threads
|
|
{
|
|
id: "arrow-reel-to-threads",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-ig-reel",
|
|
targetId: "post-threads-xpost",
|
|
color: "#000000",
|
|
},
|
|
|
|
// Threads → Bluesky
|
|
{
|
|
id: "arrow-threads-to-bluesky",
|
|
type: "folk-arrow",
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0,
|
|
rotation: 0,
|
|
sourceId: "post-threads-xpost",
|
|
targetId: "post-bluesky-launch",
|
|
color: "#0085FF",
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Ensure the campaign demo community exists and is seeded.
|
|
* Called on server startup alongside the main demo.
|
|
*/
|
|
export async function ensureCampaignDemo(): Promise<void> {
|
|
const slug = "campaign-demo";
|
|
const exists = await communityExists(slug);
|
|
|
|
if (!exists) {
|
|
await createCommunity(
|
|
"Social Media Campaign Demo",
|
|
slug,
|
|
null,
|
|
"public",
|
|
);
|
|
console.log(
|
|
"[Campaign] Created campaign-demo community with visibility: public",
|
|
);
|
|
} else {
|
|
await loadCommunity(slug);
|
|
}
|
|
|
|
// Check if already seeded
|
|
const data = getDocumentData(slug);
|
|
const shapeCount = data ? Object.keys(data.shapes || {}).length : 0;
|
|
|
|
if (shapeCount === 0) {
|
|
addShapes(slug, CAMPAIGN_SHAPES);
|
|
console.log(
|
|
`[Campaign] Seeded ${CAMPAIGN_SHAPES.length} shapes into campaign-demo`,
|
|
);
|
|
} else {
|
|
console.log(
|
|
`[Campaign] campaign-demo already has ${shapeCount} shapes`,
|
|
);
|
|
}
|
|
}
|