Add all backend files

This commit is contained in:
Your Name
2026-02-12 19:33:47 -06:00
parent f58f55204a
commit f60a0f0c6b
7 changed files with 225 additions and 1 deletions

5
.env.example Normal file
View File

@@ -0,0 +1,5 @@
STRIPE_SECRET_KEY=sk_test_your_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_secret_here
GITHUB_TOKEN=ghp_your_token_here
BASE_URL=https://context-bridge-ten.vercel.app
PORT=3000

3
.gitignore vendored
View File

@@ -1 +1,2 @@
.vercel node_modules/
.env

11
.vercel/README.txt Normal file
View File

@@ -0,0 +1,11 @@
> Why do I have a folder named ".vercel" in my project?
The ".vercel" folder is created when you link a directory to a Vercel project.
> What does the "project.json" file contain?
The "project.json" file contains:
- The ID of the Vercel project that you linked ("projectId")
- The ID of the user or team your Vercel project is owned by ("orgId")
> Should I commit the ".vercel" folder?
No, you should not share the ".vercel" folder with anyone.
Upon creation, it will be automatically added to your ".gitignore" file.

1
.vercel/project.json Normal file
View File

@@ -0,0 +1 @@
{"projectId":"prj_KL07uJYKBqS1Wpl6qrvpCPa5b7V9","orgId":"team_TRzkNju2fGETspZKM2AkELHe","projectName":"context-bridge"}

17
package.json Normal file
View File

@@ -0,0 +1,17 @@
{
"name": "context-bridge",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"dependencies": {
"express": "^4.18.2",
"stripe": "^14.0.0",
"@octokit/rest": "^20.0.2"
},
"devDependencies": {
"nodemon": "^3.0.2"
}
}

104
server.js Normal file
View File

@@ -0,0 +1,104 @@
const express = require('express');
const Stripe = require('stripe');
const { Octokit } = require('@octokit/rest');
const app = express();
const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
app.use(express.json());
app.use(express.static('public'));
// Create context gist for user
app.post('/api/create-context', async (req, res) => {
const { email, name } = req.body;
const contextTemplate = `# ${name}'s Context
**Last Updated**: ${new Date().toISOString()}
**Email**: ${email}
## Current Work
[Add what you're working on]
## Active Projects
- [Project 1]
- [Project 2]
## Context for AI Assistants
When starting a conversation, I'm currently focused on: [Fill this in]
## Instructions
Give this URL to any AI assistant: [This gist URL]
Update using: gh gist edit [gist-id] CURRENT_CONTEXT.md
`;
try {
const gist = await octokit.gists.create({
description: `${name}'s Context Bridge`,
public: true,
files: {
'CURRENT_CONTEXT.md': {
content: contextTemplate
}
}
});
res.json({
gistUrl: gist.data.html_url,
gistId: gist.data.id,
rawUrl: gist.data.files['CURRENT_CONTEXT.md'].raw_url
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Create Stripe checkout
app.post('/api/create-checkout', async (req, res) => {
const { email, priceId } = req.body;
try {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [{
price: priceId,
quantity: 1,
}],
mode: 'subscription',
success_url: `${process.env.BASE_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.BASE_URL}/`,
customer_email: email,
});
res.json({ url: session.url });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Webhook handler
app.post('/api/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
const sig = req.headers['stripe-signature'];
try {
const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// Create gist for customer
// Send welcome email with gist URL
}
res.json({ received: true });
} catch (error) {
res.status(400).send(`Webhook Error: ${error.message}`);
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

85
success.html Normal file
View File

@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Success - Context Bridge</title>
<style>
body {
font-family: Georgia, Times, serif;
max-width: 700px;
margin: 50px auto;
padding: 20px;
line-height: 1.6;
}
.success-box {
border: 2px solid #0645ad;
padding: 30px;
background: #f8f9fa;
}
h1 {
color: #0645ad;
border-bottom: 1px solid #a2a9b1;
padding-bottom: 10px;
}
code {
background: #eee;
padding: 2px 6px;
border-radius: 3px;
font-family: monospace;
}
.gist-url {
background: #fff;
border: 1px solid #a2a9b1;
padding: 15px;
margin: 20px 0;
font-family: monospace;
word-break: break-all;
}
</style>
</head>
<body>
<div class="success-box">
<h1>Welcome to Context Bridge!</h1>
<p><strong>Your context file has been created.</strong></p>
<div class="gist-url" id="gist-url">Loading your context URL...</div>
<h2>How to use it</h2>
<ol>
<li>Copy the URL above</li>
<li>When starting any AI conversation, say: <code>Read [your URL] first</code></li>
<li>The AI will understand your context immediately</li>
<li>Update your context anytime: <code>gh gist edit [gist-id] CURRENT_CONTEXT.md</code></li>
</ol>
<h2>Next steps</h2>
<ul>
<li>Edit your context file to add your current projects</li>
<li>Try it with Claude, ChatGPT, or GitHub Copilot</li>
<li>Update weekly (or whenever your focus changes)</li>
</ul>
<p><a href="/">← Back to home</a></p>
</div>
<script>
const urlParams = new URLSearchParams(window.location.search);
const sessionId = urlParams.get('session_id');
if (sessionId) {
fetch(`/api/get-context?session=${sessionId}`)
.then(r => r.json())
.then(data => {
document.getElementById('gist-url').textContent = data.gistUrl;
})
.catch(() => {
document.getElementById('gist-url').textContent = 'Check your email for your context URL';
});
}
</script>
</body>
</html>