Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
71a9fdf
Initial plan
Copilot Jan 29, 2026
48a128c
Initial exploration and planning for Social Wallet Platform
Copilot Jan 29, 2026
d46bb85
Add comprehensive documentation for Social Portfolio Platform
Copilot Jan 29, 2026
e738b5b
Add comprehensive GitHub Actions workflows for CI/CD
Copilot Jan 29, 2026
1d99fe3
Add health check and status API endpoints, enhance robots.txt
Copilot Jan 29, 2026
0f27c48
Address code review feedback and add implementation summary
Copilot Jan 29, 2026
295c095
Fix GitHub Actions workflow permissions (CodeQL security findings)
Copilot Jan 29, 2026
4bda5b9
Add comprehensive comments and improve YAML workflow documentation
Copilot Jan 29, 2026
face0a1
chore: align canonical README across root and docs/
Copilot Jan 29, 2026
6404845
Changes before error encountered
Copilot Jan 30, 2026
39ec976
fix: resolve robots.ts merge conflict - adopt main branch structure
Copilot Jan 30, 2026
e593769
chore: remove merge artifact file
Copilot Jan 30, 2026
b97fd25
Merge remote-tracking branch 'origin/main' into copilot/build-social-…
SMSDAO Jan 30, 2026
ad5412c
Revise README for SMSDAO App documentation
SMSDAO Jan 30, 2026
cee570f
Enhance README.md with documentation structure and setup
SMSDAO Jan 30, 2026
6ff9019
Add full architecture and specifications document
SMSDAO Jan 30, 2026
0f88efe
Update docs/ARCHITECTURE_FULL_SPECS.md
SMSDAO Jan 30, 2026
bab0a58
Update .github/workflows/security.yml
SMSDAO Jan 30, 2026
83f0bb0
Update README.md
SMSDAO Feb 3, 2026
6612d37
Update auto-merge.yml
SMSDAO Feb 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
# Contributions
# Contributing Guidelines

Thank you for your interest in contributing to the Ethereum Follow Protocol App!

For detailed contributing guidelines, please see our comprehensive documentation:

**[Complete Contributing Guide](../docs/CONTRIBUTING.md)**

## Quick Start

1. **Fork the repository** and clone it locally
2. **Install dependencies**: `bun install`
3. **Create a branch**: `git checkout -b feature/your-feature`
4. **Make your changes** following our code style
5. **Test your changes**: `bun lint && bun typecheck && bun run build`
6. **Commit**: Use conventional commit format
7. **Push** and create a pull request

## Resources

- [Documentation](../docs/README.md)
- [Architecture Guide](../docs/ARCHITECTURE.md)
- [Development Guidelines](../docs/CONTRIBUTING.md)
- [API Documentation](../docs/API.md)

## Code of Conduct

Be respectful, inclusive, and constructive in all interactions.

## Questions?

- **Discord**: [Discord](https://discord.efp.app)
- **Discussions**: [GitHub Discussions](https://github.com/SMSDAO/app/discussions)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent repository URL.

The discussions link points to SMSDAO/app but the PR is for ethereumfollowprotocol/app. Verify and align with the correct repository.

Suggested fix
-- **Discussions**: [GitHub Discussions](https://github.com/SMSDAO/app/discussions)
+- **Discussions**: [GitHub Discussions](https://github.com/ethereumfollowprotocol/app/discussions)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Discussions**: [GitHub Discussions](https://github.com/SMSDAO/app/discussions)
- **Discussions**: [GitHub Discussions](https://github.com/ethereumfollowprotocol/app/discussions)
🤖 Prompt for AI Agents
In @.github/CONTRIBUTING.md at line 33, The "Discussions" link in
CONTRIBUTING.md is pointing to the wrong repository (SMSDAO/app); update the URL
for the "Discussions" bullet so it references the correct repository (replace
SMSDAO/app with ethereumfollowprotocol/app) by editing the line that contains
the "**Discussions**" link.

- **Email**: [encrypted@ethfollow.xyz](mailto:encrypted@ethfollow.xyz)
117 changes: 117 additions & 0 deletions .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Auto Merge Workflow
# Automatically merges pull requests that meet all requirements
# Only runs for PRs with 'auto-merge' label or from dependabot

name: Auto Merge

on:
pull_request:
types: [opened, synchronize, reopened, labeled]
pull_request_review:
types: [submitted]
check_suite:
types: [completed]
Comment on lines +12 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

check_suite trigger will never execute the job due to missing PR context.

The check_suite event payload does not include github.event.pull_request. When a check suite completes, the job-level if condition (lines 20-22) will always evaluate to false because both github.event.pull_request.user.login and github.event.pull_request.labels are undefined.

This means auto-merge will never trigger when checks complete—only on PR events or review submissions.

Consider one of these approaches:

  1. Remove check_suite trigger and rely on pull_request + pull_request_review events only
  2. Use workflow_run trigger instead, which can access PR context
  3. Query for associated PRs within the script when handling check_suite events

Also applies to: 20-22

🤖 Prompt for AI Agents
In @.github/workflows/auto-merge.yml around lines 12 - 13, The workflow's
check_suite trigger lacks PR context so any job-level condition referencing
github.event.pull_request (e.g., checks against
github.event.pull_request.user.login or github.event.pull_request.labels) will
always be false; fix by either removing the check_suite trigger and relying on
pull_request and pull_request_review events, replace check_suite with
workflow_run so PR context is available, or keep check_suite but change the job
logic to look up associated PRs (call the GitHub API to find PRs for the check
suite and base your conditions on that result) and stop directly accessing
github.event.pull_request in the job condition.


jobs:
auto-merge:
runs-on: ubuntu-latest

# Only run for PRs with 'auto-merge' label or from dependabot
if: |
github.event.pull_request.user.login == 'dependabot[bot]' ||
contains(github.event.pull_request.labels.*.name, 'auto-merge')

# Permissions required for merging PRs
permissions:
contents: write # Write to merge commits
pull-requests: write # Update PR status

steps:
# Step 1: Checkout repository code
- name: 🔑 Checkout
uses: actions/checkout@v4

# Step 2: Display auto-merge configuration
- name: 🤖 Auto Merge Configuration
run: |
echo "Auto-merge workflow triggered"
echo "PR #${{ github.event.pull_request.number }}"
echo "Author: ${{ github.event.pull_request.user.login }}"
echo ""
echo "Requirements for auto-merge:"
echo "- All required checks must pass"
echo "- PR must be approved by maintainer"
echo "- No merge conflicts"
echo "- Branch is up to date with base"

# Step 3: Check conditions and attempt to merge
- name: ✅ Enable Auto-Merge
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;

// Verify this is a pull request event
if (!pr) {
console.log('Not a pull request event');
return;
}

// Check if PR qualifies for auto-merge
const shouldAutoMerge =
pr.user.login === 'dependabot[bot]' ||
pr.labels.some(label => label.name === 'auto-merge');

if (!shouldAutoMerge) {
console.log('PR does not qualify for auto-merge');
return;
}

console.log('PR qualifies for auto-merge');

// Verify all required checks have passed
const { data: checks } = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: pr.head.sha
});

const allChecksPassed = checks.check_runs.every(check =>
check.conclusion === 'success' || check.status === 'completed'
);

if (!allChecksPassed) {
console.log('Not all checks have passed yet, waiting...');
return;
}
Comment on lines +80 to +87
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Empty check_runs array would allow merge without any checks.

Array.prototype.every() returns true for an empty array. If no check runs exist (checks haven't registered yet, or repo has no CI configured), the workflow will proceed to merge.

🐛 Proposed fix
             const allChecksPassed = checks.check_runs.every(check => 
               check.conclusion === 'success'
             );
             
-            if (!allChecksPassed) {
+            if (checks.check_runs.length === 0) {
+              console.log('No check runs found, waiting for checks to register...');
+              return;
+            }
+            
+            if (!allChecksPassed) {
               console.log('Not all checks have passed yet, waiting...');
               return;
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const allChecksPassed = checks.check_runs.every(check =>
check.conclusion === 'success'
);
if (!allChecksPassed) {
console.log('Not all checks have passed yet, waiting...');
return;
}
const allChecksPassed = checks.check_runs.every(check =>
check.conclusion === 'success'
);
if (checks.check_runs.length === 0) {
console.log('No check runs found, waiting for checks to register...');
return;
}
if (!allChecksPassed) {
console.log('Not all checks have passed yet, waiting...');
return;
}
🤖 Prompt for AI Agents
In @.github/workflows/auto-merge.yml around lines 80 - 87, The workflow
currently treats an empty checks.check_runs array as passing because
allChecksPassed uses checks.check_runs.every(...); update the logic so it
requires at least one check run and that all runs succeeded (e.g., replace the
allChecksPassed assignment with a condition that checks.check_runs.length > 0 &&
checks.check_runs.every(check => check.conclusion === 'success') and keep the
existing handling when the condition is false), ensuring the merge won't proceed
when no checks exist.


// Verify PR has been approved (skip for dependabot)
const { data: reviews } = await github.rest.pulls.listReviews({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});

const isApproved = reviews.some(review => review.state === 'APPROVED');

if (!isApproved && pr.user.login !== 'dependabot[bot]') {
console.log('PR not approved yet, waiting for review...');
return;
}
Comment on lines +96 to +101
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Consider blocking merge when changes are requested.

The current logic only checks for APPROVED reviews but doesn't explicitly block when CHANGES_REQUESTED reviews exist. A PR could have both an approval and a request for changes.

💡 Suggested improvement
             const isApproved = reviews.some(review => review.state === 'APPROVED');
+            const hasChangesRequested = reviews.some(review => review.state === 'CHANGES_REQUESTED');
             
-            if (!isApproved && pr.user.login !== 'dependabot[bot]') {
+            if (hasChangesRequested) {
+              console.log('Changes requested, cannot auto-merge');
+              return;
+            }
+            
+            if (!isApproved && pr.user.login !== 'dependabot[bot]') {
               console.log('PR not approved yet, waiting for review...');
               return;
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isApproved = reviews.some(review => review.state === 'APPROVED');
if (!isApproved && pr.user.login !== 'dependabot[bot]') {
console.log('PR not approved yet, waiting for review...');
return;
}
const isApproved = reviews.some(review => review.state === 'APPROVED');
const hasChangesRequested = reviews.some(review => review.state === 'CHANGES_REQUESTED');
if (hasChangesRequested) {
console.log('Changes requested, cannot auto-merge');
return;
}
if (!isApproved && pr.user.login !== 'dependabot[bot]') {
console.log('PR not approved yet, waiting for review...');
return;
}
🤖 Prompt for AI Agents
In @.github/workflows/auto-merge.yml around lines 96 - 101, Update the merge
gating logic to also block when any review has state 'CHANGES_REQUESTED' instead
of only checking for approvals; locate the code that computes isApproved
(reviews.some(review => review.state === 'APPROVED')) and the conditional that
returns early for non-approved PRs (and exempting pr.user.login ===
'dependabot[bot]'), and add a check like hasChangesRequested =
reviews.some(review => review.state === 'CHANGES_REQUESTED') and prevent merging
when hasChangesRequested is true (log a clear message and return) even if
isApproved is true.


console.log('All conditions met, attempting to merge...');

// Attempt to merge the PR
try {
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
merge_method: 'squash'
});
console.log('✅ PR merged successfully');
} catch (error) {
console.log('Could not merge PR:', error.message);
console.log('This may be due to merge conflicts or other restrictions');
}
115 changes: 115 additions & 0 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Build Documentation Workflow
# Validates documentation files on changes to docs/ directory
# Checks for broken links and ensures all required documentation exists

name: Build Documentation

on:
pull_request:
paths:
- 'docs/**'
- '.github/workflows/build-docs.yml'
push:
branches: [main]
paths:
- 'docs/**'
workflow_dispatch:

jobs:
build-docs:
runs-on: ubuntu-latest
timeout-minutes: 5

# Minimal permissions - only needs to read repository content
permissions:
contents: read

steps:
# Step 1: Checkout repository code
- name: 🔑 Checkout
uses: actions/checkout@v4

# Step 2: Setup Node.js for markdown tools
- name: 📦 Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

# Step 3: Install markdown link checker tool
- name: 📥 Install markdown-link-check
run: npm install -g markdown-link-check

# Step 4: Check all markdown files for broken links
- name: 🔗 Check Markdown Links
run: |
# Create config file for markdown-link-check
cat > .markdown-link-check.json << 'EOF'
{
"ignorePatterns": [
{
"pattern": "^http://localhost"
},
{
"pattern": "^https://efp.app"
}
],
"timeout": "20s",
"retryOn429": true,
"retryCount": 3,
"fallbackRetryDelay": "30s"
}
EOF

# Check all markdown files
for file in docs/*.md; do
if [ -f "$file" ]; then
echo "Checking $file..."
markdown-link-check "$file" --config .markdown-link-check.json || true
fi
done

# Step 5: Validate that all required documentation files exist
- name: 📝 Validate Documentation Structure
run: |
required_files=(
"docs/README.md"
"docs/ARCHITECTURE.md"
"docs/API.md"
"docs/FEATURES.md"
"docs/DEPLOYMENT.md"
"docs/WORKFLOWS.md"
"docs/MONITORING.md"
"docs/SEO.md"
"docs/CONTRIBUTING.md"
)

missing_files=()
for file in "${required_files[@]}"; do
if [ ! -f "$file" ]; then
missing_files+=("$file")
fi
done

if [ ${#missing_files[@]} -gt 0 ]; then
echo "❌ Missing required documentation files:"
printf '%s\n' "${missing_files[@]}"
exit 1
fi

echo "✅ All required documentation files are present"

# Step 6: Display documentation statistics
- name: 📊 Documentation Statistics
run: |
echo "📊 Documentation Statistics:"
echo "Total markdown files: $(find docs -name '*.md' | wc -l)"
echo "Total lines: $(find docs -name '*.md' -exec wc -l {} + | tail -1)"
echo ""
echo "Files by size:"
find docs -name '*.md' -exec wc -l {} + | sort -rn | head -10

# Step 7: Success message
- name: ✅ Documentation Build Complete
if: success()
run: echo "Documentation validation passed successfully!"
88 changes: 88 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Deploy Workflow
# Deploys the application to production on merge to main branch
# Runs full test suite before deployment to ensure quality

name: Deploy

on:
push:
branches: [main]
workflow_dispatch:

# Prevent concurrent deployments
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

# Environment variables for deployment
env:
NODE_OPTIONS: '--no-warnings'
NEXT_TELEMETRY_DISABLED: '1'

jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 20
environment: production

# Minimal permissions for deployment
permissions:
contents: read

steps:
# Step 1: Checkout the repository code
- name: 🔑 Checkout
uses: actions/checkout@v4

# Step 2: Setup Bun runtime
- name: 📦 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

# Step 3: Cache dependencies for faster builds
- name: 📥 Cache Dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
.next/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
restore-keys: |
${{ runner.os }}-bun-

# Step 4: Install project dependencies
- name: 🔧 Install Dependencies
run: bun install --frozen-lockfile

# Step 5: Run tests to verify code quality before deployment
- name: 🔍 Run Tests
run: |
bun lint
bun typecheck

# Step 6: Build the production application
- name: 🏗️ Build Application
run: bun run build
env:
NODE_ENV: production
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID }}

# Step 7: Deploy to Vercel (configured via Vercel GitHub integration)
- name: 🚀 Deploy to Vercel
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
echo "Deployment to Vercel is configured via Vercel GitHub integration"
echo "Visit https://vercel.com/dashboard to configure automatic deployments"
echo "Commit SHA: ${{ github.sha }}"

# Step 8: Display deployment summary
- name: 📊 Deployment Summary
if: success()
run: |
echo "✅ Deployment completed successfully!"
echo "Commit: ${{ github.sha }}"
echo "Branch: ${{ github.ref_name }}"
echo "Author: ${{ github.actor }}"
echo "Message: ${{ github.event.head_commit.message }}"
Comment on lines +80 to +88
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Script injection vulnerability via commit message.

github.event.head_commit.message is untrusted user input. Using it directly in a shell script allows an attacker to inject arbitrary commands via a malicious commit message. Pass it through an environment variable instead.

Recommended fix
       # Step 8: Display deployment summary
       - name: 📊 Deployment Summary
         if: success()
+        env:
+          COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
         run: |
           echo "✅ Deployment completed successfully!"
           echo "Commit: ${{ github.sha }}"
           echo "Branch: ${{ github.ref_name }}"
           echo "Author: ${{ github.actor }}"
-          echo "Message: ${{ github.event.head_commit.message }}"
+          echo "Message: $COMMIT_MESSAGE"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Step 8: Display deployment summary
- name: 📊 Deployment Summary
if: success()
run: |
echo "✅ Deployment completed successfully!"
echo "Commit: ${{ github.sha }}"
echo "Branch: ${{ github.ref_name }}"
echo "Author: ${{ github.actor }}"
echo "Message: ${{ github.event.head_commit.message }}"
# Step 8: Display deployment summary
- name: 📊 Deployment Summary
if: success()
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
run: |
echo "✅ Deployment completed successfully!"
echo "Commit: ${{ github.sha }}"
echo "Branch: ${{ github.ref_name }}"
echo "Author: ${{ github.actor }}"
echo "Message: $COMMIT_MESSAGE"
🧰 Tools
🪛 actionlint (1.7.10)

[error] 83-83: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)

🤖 Prompt for AI Agents
In @.github/workflows/deploy.yml around lines 80 - 88, The deployment summary
step ("📊 Deployment Summary") currently injects untrusted input via ${
github.event.head_commit.message } directly into the shell run block; instead
pass the commit message through a workflow environment variable (e.g.,
COMMIT_MESSAGE using the YAML env: mapping) and remove the inline github.event.*
expansion from the run script, then print it safely (e.g., using printf '%s\n'
"$COMMIT_MESSAGE" or echo "$COMMIT_MESSAGE") so the shell does not interpret
special characters—update the step to set env: COMMIT_MESSAGE: ${{
github.event.head_commit.message }}, use COMMIT_MESSAGE in the run, and ensure
the variable is properly quoted when echoed.

Loading
Loading