refactor: update membership agreement and conflict resolution framework templates to utilize centralized cooperative information, enhance decision framework handling, and improve overall layout for better user experience

This commit is contained in:
Jennie Robinson Faber 2025-09-10 08:32:57 +01:00
parent f1889b3a70
commit 7b4fb6c2fd
5 changed files with 510 additions and 703 deletions

View file

@ -424,7 +424,8 @@ const formatObjectAsMarkdown = (obj: any): string => {
// Membership Agreement formatting - Complete document with all static and dynamic content
const formatMembershipAgreementAsText = (data: any): string => {
const formData = data.formData || {};
let content = `MEMBERSHIP AGREEMENT\n====================\n\n`;
const cooperativeName = data.cooperativeName || formData.cooperativeName || "the cooperative";
let content = "";
// Section 1: Who We Are
content += `1. WHO WE ARE\n-------------\n\n`;
@ -459,18 +460,25 @@ const formatMembershipAgreementAsText = (data: any): string => {
content += `New members join through a consent process, which means existing members must agree that adding this person won't harm the cooperative.\n\n`;
content += `1. Trial period of ${formData.trialPeriodMonths || 3} months working together\n`;
content += `2. Values alignment conversation\n`;
content += `3. Consent decision by current members\n`;
content += `4. Optional - Equal buy-in contribution of $${formData.buyInAmount || "[amount]"} (can be paid over time or waived based on need)\n\n`;
content += `3. Optional - Equal buy-in contribution of $${formData.buyInAmount || "[amount]"} (can be paid over time or waived based on need)\n\n`;
content += `Leaving the Cooperative:\n`;
content += `Members can leave anytime with ${formData.noticeDays || 30} days notice. The cooperative will:\n\n`;
content += `Members can leave anytime with ${formData.noticeDays || 30} days notice. ${cooperativeName} will:\n\n`;
content += `• Pay out their share of any surplus within ${formData.surplusPayoutDays || 30} days\n`;
content += `• Return their buy-in contribution within ${formData.buyInReturnDays || 90} days\n`;
content += `• Maintain respectful ongoing relationships when possible\n\n`;
// Section 3: How We Make Decisions
content += `3. HOW WE MAKE DECISIONS\n------------------------\n\n`;
content += `Consent-Based Decisions:\nWe use consent, not consensus. This means we move forward when no one has a principled objection that would harm the cooperative. An objection must explain how the proposal would contradict our values or threaten our sustainability.\n\n`;
content += `Primary Decision Framework: ${data.decisionFrameworkName || "Consent-Based - No one objects strongly enough to block"}\n\n`;
const frameworkDetails = data.decisionFrameworkDetails || {};
if (frameworkDetails.practicalDescription) {
content += `${frameworkDetails.practicalDescription}\n\n`;
} else {
content += `We use consent, not consensus. This means we move forward when no one has a principled objection that would harm our organization. An objection must explain how the proposal would contradict our values or threaten our sustainability.\n\n`;
}
content += `Day-to-Day Decisions:\nDecisions under $${formData.dayToDayLimit || 100} can be made by any member. Just tell others what you did at the next meeting.\n\n`;
@ -481,7 +489,7 @@ const formatMembershipAgreementAsText = (data: any): string => {
content += `• Changing this agreement\n`;
content += `• Taking on debt over $${formData.majorDebtThreshold || 5000}\n`;
content += `• Fundamental changes to our purpose or structure\n`;
content += `• Dissolution of the cooperative\n\n`;
content += `• Dissolution of ${cooperativeName}\n\n`;
content += `Meeting Structure:\n`;
content += `• Regular meetings happen ${formData.meetingFrequency || "weekly"}\n`;
@ -491,12 +499,12 @@ const formatMembershipAgreementAsText = (data: any): string => {
// Section 4: Money and Labour
content += `4. MONEY AND LABOUR\n-------------------\n\n`;
content += `Equal Ownership:\nEach member owns an equal share of the cooperative, regardless of hours worked or tenure.\n\n`;
content += `Equal Ownership:\nEach member owns an equal share of ${cooperativeName}, regardless of hours worked or tenure.\n\n`;
content += `Paying Ourselves:\n`;
const payPolicy = formData.payPolicy || "equal-pay";
const payPolicyName = payPolicy.replace('-', ' ').replace(/\b\w/g, (l: string) => l.toUpperCase());
content += `Pay Policy: ${payPolicyName}\n\n`;
content += `Pay Policy: ${data.payPolicyName || payPolicyName}\n\n`;
if (payPolicy === 'equal-pay') {
content += `All members receive equal compensation regardless of role or hours worked.\n`;
@ -516,7 +524,7 @@ const formatMembershipAgreementAsText = (data: any): string => {
}
content += `\nPayment Schedule:\n`;
content += `• Paid on the ${formData.paymentDay || 15} of each month\n`;
content += `• Paid on the ${data.paymentDayLabel || formData.paymentDay || 15} of each month\n`;
content += `• Surplus (profit) distributed equally every ${formData.surplusFrequency || "quarter"}\n\n`;
content += `Work Expectations:\n`;
@ -556,11 +564,13 @@ const formatMembershipAgreementAsText = (data: any): string => {
// Section 7: Changing This Agreement
content += `7. CHANGING THIS AGREEMENT\n--------------------------\n\n`;
content += `This is a living document. We review it every ${formData.reviewFrequency || "year"} and update it through our consent process. Small clarifications can happen anytime; structural changes need full member consent.\n\n`;
const frameworkLabel = data.decisionFrameworkLabel || "consent-based decision";
const structuralReq = data.structuralChangeRequirement || "full member consent";
content += `This is a living document. We review it every ${formData.reviewFrequency || "year"} and update it through our ${frameworkLabel} process. Small clarifications can happen anytime; structural changes need ${structuralReq}.\n\n`;
// Section 8: If We Need to Close
content += `8. IF WE NEED TO CLOSE\n----------------------\n\n`;
content += `If the cooperative dissolves:\n`;
content += `If ${cooperativeName} dissolves:\n`;
content += `1. Pay all debts and obligations\n`;
content += `2. Return member contributions\n`;
content += `3. Distribute remaining assets equally among members\n`;
@ -569,19 +579,26 @@ const formatMembershipAgreementAsText = (data: any): string => {
}
content += `\n`;
// Section 9: Legal Bits
content += `9. LEGAL BITS\n-------------\n\n`;
content += `Legal Structure: ${formData.legalStructure || "[Cooperative corporation, LLC, partnership, etc.]"}\n`;
content += `Registered in: ${formData.registeredLocation || "[State/Province]"}\n`;
content += `Fiscal Year-End: ${formData.fiscalYearEndMonth || "December"} ${formData.fiscalYearEndDay || 31}\n\n`;
content += `This agreement works alongside but doesn't replace our legal incorporation documents. Where they conflict, we follow the law but work to align our legal structure with our values.\n\n`;
// Section 9: Legal Registration
content += `9. LEGAL REGISTRATION\n---------------------\n\n`;
if (formData.isLegallyRegistered) {
content += `Legal Structure: ${formData.legalStructure || "[Cooperative corporation, LLC, partnership, etc.]"}\n`;
content += `Registered in: ${formData.registeredLocation || "[State/Province]"}\n`;
content += `Fiscal Year-End: ${formData.fiscalYearEndMonth || "December"} ${formData.fiscalYearEndDay || 31}\n\n`;
content += `This agreement works alongside but doesn't replace our legal incorporation documents. Where they conflict, we follow the law but work to align our legal structure with our values.\n\n`;
} else {
const thisCooperative = cooperativeName === "the cooperative" ? "This cooperative" : cooperativeName;
content += `${thisCooperative} operates as an informal collective. If we decide to register legally in the future, we'll update this section with our legal structure details.\n\n`;
}
return content;
};
const formatMembershipAgreementAsMarkdown = (data: any): string => {
const formData = data.formData || {};
let content = `# Membership Agreement\n\n`;
const cooperativeName = data.cooperativeName || formData.cooperativeName || "the cooperative";
let content = "";
// Section 1: Who We Are
content += `## 1. Who We Are\n\n`;
@ -616,19 +633,26 @@ const formatMembershipAgreementAsMarkdown = (data: any): string => {
content += `New members join through a consent process, which means existing members must agree that adding this person won't harm the cooperative.\n\n`;
content += `1. Trial period of **${formData.trialPeriodMonths || 3} months** working together\n`;
content += `2. Values alignment conversation\n`;
content += `3. Consent decision by current members\n`;
content += `4. Optional - Equal buy-in contribution of **$${formData.buyInAmount || "[amount]"}** (can be paid over time or waived based on need)\n\n`;
content += `3. Optional - Equal buy-in contribution of **$${formData.buyInAmount || "[amount]"}** (can be paid over time or waived based on need)\n\n`;
content += `### Leaving the Cooperative\n\n`;
content += `Members can leave anytime with **${formData.noticeDays || 30} days** notice. The cooperative will:\n\n`;
content += `Members can leave anytime with **${formData.noticeDays || 30} days** notice. ${cooperativeName} will:\n\n`;
content += `- Pay out their share of any surplus within **${formData.surplusPayoutDays || 30} days**\n`;
content += `- Return their buy-in contribution within **${formData.buyInReturnDays || 90} days**\n`;
content += `- Maintain respectful ongoing relationships when possible\n\n`;
// Section 3: How We Make Decisions
content += `## 3. How We Make Decisions\n\n`;
content += `### Consent-Based Decisions\n\n`;
content += `We use consent, not consensus. This means we move forward when no one has a principled objection that would harm the cooperative. An objection must explain how the proposal would contradict our values or threaten our sustainability.\n\n`;
content += `### Primary Decision Framework\n\n`;
content += `**${data.decisionFrameworkName || "Consent-Based - No one objects strongly enough to block"}**\n\n`;
const frameworkDetails = data.decisionFrameworkDetails || {};
if (frameworkDetails.practicalDescription) {
content += `${frameworkDetails.practicalDescription}\n\n`;
} else {
content += `We use consent, not consensus. This means we move forward when no one has a principled objection that would harm our organization. An objection must explain how the proposal would contradict our values or threaten our sustainability.\n\n`;
}
content += `### Day-to-Day Decisions\n\n`;
content += `Decisions under **$${formData.dayToDayLimit || 100}** can be made by any member. Just tell others what you did at the next meeting.\n\n`;
@ -642,7 +666,7 @@ const formatMembershipAgreementAsMarkdown = (data: any): string => {
content += `- Changing this agreement\n`;
content += `- Taking on debt over **$${formData.majorDebtThreshold || 5000}**\n`;
content += `- Fundamental changes to our purpose or structure\n`;
content += `- Dissolution of the cooperative\n\n`;
content += `- Dissolution of ${cooperativeName}\n\n`;
content += `### Meeting Structure\n\n`;
content += `- Regular meetings happen **${formData.meetingFrequency || "weekly"}**\n`;
@ -653,12 +677,12 @@ const formatMembershipAgreementAsMarkdown = (data: any): string => {
// Section 4: Money and Labour
content += `## 4. Money and Labour\n\n`;
content += `### Equal Ownership\n\n`;
content += `Each member owns an equal share of the cooperative, regardless of hours worked or tenure.\n\n`;
content += `Each member owns an equal share of ${cooperativeName}, regardless of hours worked or tenure.\n\n`;
content += `### Paying Ourselves\n\n`;
const payPolicy = formData.payPolicy || "equal-pay";
const payPolicyName = payPolicy.replace('-', ' ').replace(/\b\w/g, (l: string) => l.toUpperCase());
content += `**Pay Policy:** ${payPolicyName}\n\n`;
content += `**Pay Policy:** ${data.payPolicyName || payPolicyName}\n\n`;
if (payPolicy === 'equal-pay') {
content += `All members receive equal compensation regardless of role or hours worked.\n\n`;
@ -678,7 +702,7 @@ const formatMembershipAgreementAsMarkdown = (data: any): string => {
}
content += `\n**Payment Schedule:**\n\n`;
content += `- Paid on the **${formData.paymentDay || 15}** of each month\n`;
content += `- Paid on the **${data.paymentDayLabel || formData.paymentDay || 15}** of each month\n`;
content += `- Surplus (profit) distributed equally every **${formData.surplusFrequency || "quarter"}**\n\n`;
content += `### Work Expectations\n\n`;
@ -718,11 +742,13 @@ const formatMembershipAgreementAsMarkdown = (data: any): string => {
// Section 7: Changing This Agreement
content += `## 7. Changing This Agreement\n\n`;
content += `This is a living document. We review it every **${formData.reviewFrequency || "year"}** and update it through our consent process. Small clarifications can happen anytime; structural changes need full member consent.\n\n`;
const frameworkLabel = data.decisionFrameworkLabel || "consent-based decision";
const structuralReq = data.structuralChangeRequirement || "full member consent";
content += `This is a living document. We review it every **${formData.reviewFrequency || "year"}** and update it through our ${frameworkLabel} process. Small clarifications can happen anytime; structural changes need ${structuralReq}.\n\n`;
// Section 8: If We Need to Close
content += `## 8. If We Need to Close\n\n`;
content += `If the cooperative dissolves:\n\n`;
content += `If ${cooperativeName} dissolves:\n\n`;
content += `1. Pay all debts and obligations\n`;
content += `2. Return member contributions\n`;
content += `3. Distribute remaining assets equally among members\n`;
@ -731,12 +757,18 @@ const formatMembershipAgreementAsMarkdown = (data: any): string => {
}
content += `\n`;
// Section 9: Legal Bits
content += `## 9. Legal Bits\n\n`;
content += `- **Legal Structure:** ${formData.legalStructure || "[Cooperative corporation, LLC, partnership, etc.]"}\n`;
content += `- **Registered in:** ${formData.registeredLocation || "[State/Province]"}\n`;
content += `- **Fiscal Year-End:** ${formData.fiscalYearEndMonth || "December"} ${formData.fiscalYearEndDay || 31}\n\n`;
content += `This agreement works alongside but doesn't replace our legal incorporation documents. Where they conflict, we follow the law but work to align our legal structure with our values.\n\n`;
// Section 9: Legal Registration
content += `## 9. Legal Registration\n\n`;
if (formData.isLegallyRegistered) {
content += `- **Legal Structure:** ${formData.legalStructure || "[Cooperative corporation, LLC, partnership, etc.]"}\n`;
content += `- **Registered in:** ${formData.registeredLocation || "[State/Province]"}\n`;
content += `- **Fiscal Year-End:** ${formData.fiscalYearEndMonth || "December"} ${formData.fiscalYearEndDay || 31}\n\n`;
content += `This agreement works alongside but doesn't replace our legal incorporation documents. Where they conflict, we follow the law but work to align our legal structure with our values.\n\n`;
} else {
const thisCooperative = cooperativeName === "the cooperative" ? "This cooperative" : cooperativeName;
content += `${thisCooperative} operates as an informal collective. If we decide to register legally in the future, we'll update this section with our legal structure details.\n\n`;
}
return content;
};