- Create Economist SubmissionTracking package correctly: * mainArticle = full blog post content * coverLetter = 216-word SIR— letter * Links to blog post via blogPostId - Archive 'Letter to The Economist' from blog posts (it's the cover letter) - Fix date display on article cards (use published_at) - Target publication already displaying via blue badge Database changes: - Make blogPostId optional in SubmissionTracking model - Economist package ID: 68fa85ae49d4900e7f2ecd83 - Le Monde package ID: 68fa2abd2e6acd5691932150 Next: Enhanced modal with tabs, validation, export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
540 lines
14 KiB
Markdown
540 lines
14 KiB
Markdown
# Koha Production Deployment Guide
|
|
## Deploy Without Live Stripe Integration
|
|
|
|
**Date:** 2025-10-08
|
|
**Status:** Pre-Stripe Deployment
|
|
**Goal:** Deploy all Koha infrastructure to production, but keep user-facing UI disabled until Stripe is configured
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
This guide walks through deploying the Koha donation system to production in a "staging" mode - all code deployed, database initialized, but public access disabled until Stripe keys are configured.
|
|
|
|
**Why Deploy Now:**
|
|
- Test production infrastructure before Stripe integration
|
|
- Verify database setup and migrations
|
|
- Ensure backend API works in production environment
|
|
- Frontend code ready for immediate activation when Stripe is configured
|
|
|
|
**What's NOT Active:**
|
|
- Public navigation links to Koha pages
|
|
- Stripe payment processing
|
|
- Live donation functionality
|
|
|
|
---
|
|
|
|
## Phase 1: Database Initialization
|
|
|
|
### 1.1 SSH into Production Server
|
|
|
|
```bash
|
|
ssh -i /home/theflow/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net
|
|
```
|
|
|
|
### 1.2 Navigate to Project Directory
|
|
|
|
```bash
|
|
cd /var/www/tractatus
|
|
```
|
|
|
|
### 1.3 Run Koha Database Initialization
|
|
|
|
```bash
|
|
node scripts/init-koha.js
|
|
```
|
|
|
|
**Expected Output:**
|
|
```
|
|
[KOHA] Initializing database...
|
|
✓ Collection 'koha_donations' exists
|
|
✓ Created index on status
|
|
✓ Created index on frequency
|
|
✓ Created index on stripe.subscription_id
|
|
✓ Created index on stripe.payment_intent_id
|
|
✓ Created index on donor.email
|
|
✓ Created index on created_at
|
|
✓ Created index on public_acknowledgement
|
|
[KOHA] Database initialization complete
|
|
```
|
|
|
|
### 1.4 Verify Collection Created
|
|
|
|
```bash
|
|
mongosh tractatus_prod --eval "db.koha_donations.getIndexes()"
|
|
```
|
|
|
|
**Expected:** 10 indexes (7 custom + 3 default)
|
|
|
|
---
|
|
|
|
## Phase 2: Environment Configuration
|
|
|
|
### 2.1 Update Production .env
|
|
|
|
Edit `/var/www/tractatus/.env` and add:
|
|
|
|
```bash
|
|
# Koha Donation System (Placeholder - not active)
|
|
STRIPE_SECRET_KEY=sk_test_PLACEHOLDER_REPLACE_NEXT_WEEK
|
|
STRIPE_PUBLISHABLE_KEY=pk_test_PLACEHOLDER_REPLACE_NEXT_WEEK
|
|
STRIPE_KOHA_WEBHOOK_SECRET=whsec_PLACEHOLDER_REPLACE_NEXT_WEEK
|
|
STRIPE_KOHA_5_PRICE_ID=price_PLACEHOLDER_REPLACE_NEXT_WEEK
|
|
STRIPE_KOHA_15_PRICE_ID=price_PLACEHOLDER_REPLACE_NEXT_WEEK
|
|
STRIPE_KOHA_50_PRICE_ID=price_PLACEHOLDER_REPLACE_NEXT_WEEK
|
|
|
|
# Frontend URL
|
|
FRONTEND_URL=https://agenticgovernance.digital
|
|
```
|
|
|
|
**Note:** These placeholder values will prevent Stripe operations from executing but allow the code to load.
|
|
|
|
### 2.2 Verify Environment Variables
|
|
|
|
```bash
|
|
grep STRIPE /var/www/tractatus/.env
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 3: Deploy Code
|
|
|
|
### 3.1 From Local Machine, rsync New Files
|
|
|
|
```bash
|
|
# Deploy backend files
|
|
rsync -avz -e "ssh -i /home/theflow/.ssh/tractatus_deploy" \
|
|
/home/theflow/projects/tractatus/src/config/currencies.config.js \
|
|
/home/theflow/projects/tractatus/src/services/koha.service.js \
|
|
/home/theflow/projects/tractatus/src/controllers/koha.controller.js \
|
|
/home/theflow/projects/tractatus/src/models/Donation.model.js \
|
|
/home/theflow/projects/tractatus/src/routes/koha.routes.js \
|
|
ubuntu@vps-93a693da.vps.ovh.net:/var/www/tractatus/src/
|
|
|
|
# Deploy frontend files
|
|
rsync -avz -e "ssh -i /home/theflow/.ssh/tractatus_deploy" \
|
|
/home/theflow/projects/tractatus/public/koha.html \
|
|
/home/theflow/projects/tractatus/public/privacy.html \
|
|
ubuntu@vps-93a693da.vps.ovh.net:/var/www/tractatus/public/
|
|
|
|
rsync -avz -e "ssh -i /home/theflow/.ssh/tractatus_deploy" \
|
|
/home/theflow/projects/tractatus/public/koha/ \
|
|
ubuntu@vps-93a693da.vps.ovh.net:/var/www/tractatus/public/koha/
|
|
|
|
rsync -avz -e "ssh -i /home/theflow/.ssh/tractatus_deploy" \
|
|
/home/theflow/projects/tractatus/public/js/utils/currency.js \
|
|
/home/theflow/projects/tractatus/public/js/components/currency-selector.js \
|
|
/home/theflow/projects/tractatus/public/js/components/footer.js \
|
|
ubuntu@vps-93a693da.vps.ovh.net:/var/www/tractatus/public/js/
|
|
|
|
# Deploy scripts
|
|
rsync -avz -e "ssh -i /home/theflow/.ssh/tractatus_deploy" \
|
|
/home/theflow/projects/tractatus/scripts/init-koha.js \
|
|
ubuntu@vps-93a693da.vps.ovh.net:/var/www/tractatus/scripts/
|
|
```
|
|
|
|
### 3.2 Verify Files Deployed
|
|
|
|
SSH into production and check:
|
|
|
|
```bash
|
|
ssh -i /home/theflow/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net \
|
|
"ls -la /var/www/tractatus/src/config/currencies.config.js && \
|
|
ls -la /var/www/tractatus/public/koha.html && \
|
|
ls -la /var/www/tractatus/public/privacy.html"
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 4: Add "Coming Soon" Overlay
|
|
|
|
### 4.1 Create Coming Soon Overlay Component
|
|
|
|
Create `/var/www/tractatus/public/js/components/coming-soon-overlay.js`:
|
|
|
|
```javascript
|
|
/**
|
|
* Coming Soon Overlay
|
|
* Displays over Koha pages until Stripe is configured
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Check if we should show the overlay
|
|
const shouldShowOverlay = () => {
|
|
// Only show on Koha pages
|
|
const isKohaPage = window.location.pathname.includes('/koha');
|
|
return isKohaPage;
|
|
};
|
|
|
|
// Create and inject overlay
|
|
if (shouldShowOverlay()) {
|
|
const overlayHTML = `
|
|
<div id="coming-soon-overlay" style="
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.95);
|
|
z-index: 9999;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
backdrop-filter: blur(10px);
|
|
">
|
|
<div style="
|
|
background: white;
|
|
padding: 3rem;
|
|
border-radius: 1rem;
|
|
max-width: 600px;
|
|
text-align: center;
|
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
">
|
|
<h1 style="
|
|
font-size: 2.5rem;
|
|
font-weight: bold;
|
|
color: #1f2937;
|
|
margin-bottom: 1rem;
|
|
">
|
|
Koha Donation System
|
|
</h1>
|
|
<p style="
|
|
font-size: 1.25rem;
|
|
color: #6b7280;
|
|
margin-bottom: 2rem;
|
|
">
|
|
Coming Soon
|
|
</p>
|
|
<div style="
|
|
background: #eff6ff;
|
|
border-left: 4px solid #3b82f6;
|
|
padding: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
text-align: left;
|
|
">
|
|
<p style="color: #1e40af; margin-bottom: 0.5rem;">
|
|
<strong>What is Koha?</strong>
|
|
</p>
|
|
<p style="color: #1e3a8a; font-size: 0.875rem; margin: 0;">
|
|
Koha (Māori for "gift") is our upcoming donation system to support the Tractatus Framework.
|
|
We're currently finalizing payment processing integration and will launch soon.
|
|
</p>
|
|
</div>
|
|
<p style="
|
|
color: #6b7280;
|
|
font-size: 0.875rem;
|
|
margin-bottom: 1.5rem;
|
|
">
|
|
Infrastructure deployed and ready. Payment processing activation in progress.
|
|
</p>
|
|
<a href="/" style="
|
|
display: inline-block;
|
|
background: #3b82f6;
|
|
color: white;
|
|
padding: 0.75rem 2rem;
|
|
border-radius: 0.5rem;
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
transition: background 0.2s;
|
|
">
|
|
Return to Homepage
|
|
</a>
|
|
<p style="
|
|
margin-top: 1.5rem;
|
|
font-size: 0.75rem;
|
|
color: #9ca3af;
|
|
">
|
|
Questions? Contact <a href="mailto:support@agenticgovernance.digital" style="color: #3b82f6;">support@agenticgovernance.digital</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
document.body.insertAdjacentHTML('beforeend', overlayHTML);
|
|
}
|
|
})();
|
|
```
|
|
|
|
### 4.2 Add Overlay to All Koha Pages
|
|
|
|
SSH into production and edit these files to add the overlay script:
|
|
|
|
```bash
|
|
# Add to koha.html, transparency.html, success.html
|
|
# Insert before closing </body> tag:
|
|
<script src="/js/components/coming-soon-overlay.js"></script>
|
|
```
|
|
|
|
**Files to edit:**
|
|
- `/var/www/tractatus/public/koha.html`
|
|
- `/var/www/tractatus/public/koha/transparency.html`
|
|
- `/var/www/tractatus/public/koha/success.html`
|
|
|
|
---
|
|
|
|
## Phase 5: Modify API Endpoints for Pre-Launch
|
|
|
|
### 5.1 Add Stripe Configuration Check
|
|
|
|
Edit `/var/www/tractatus/src/controllers/koha.controller.js`:
|
|
|
|
Add at the top of `createCheckout`:
|
|
|
|
```javascript
|
|
async createCheckout(req, res) {
|
|
try {
|
|
// Check if Stripe is configured
|
|
if (!process.env.STRIPE_SECRET_KEY ||
|
|
process.env.STRIPE_SECRET_KEY.includes('PLACEHOLDER')) {
|
|
return res.status(503).json({
|
|
success: false,
|
|
error: 'Donation system not yet active',
|
|
message: 'The Koha donation system is currently being configured. Please check back soon.'
|
|
});
|
|
}
|
|
|
|
// Rest of existing code...
|
|
```
|
|
|
|
### 5.2 Add Configuration Check to Transparency Endpoint
|
|
|
|
Similar check in `getTransparency` method:
|
|
|
|
```javascript
|
|
async getTransparency(req, res) {
|
|
try {
|
|
// Allow transparency data even without Stripe configured
|
|
// (will return empty data initially)
|
|
|
|
// Rest of existing code...
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 6: Restart Production Server
|
|
|
|
### 6.1 Restart Node Application
|
|
|
|
```bash
|
|
ssh -i /home/theflow/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net
|
|
|
|
# Stop current process
|
|
sudo systemctl stop tractatus
|
|
|
|
# Start with new code
|
|
sudo systemctl start tractatus
|
|
|
|
# Verify running
|
|
sudo systemctl status tractatus
|
|
```
|
|
|
|
### 6.2 Check Server Logs
|
|
|
|
```bash
|
|
sudo journalctl -u tractatus -n 50 --no-pager
|
|
```
|
|
|
|
**Expected:** No errors, Koha routes loaded
|
|
|
|
---
|
|
|
|
## Phase 7: Testing
|
|
|
|
### 7.1 Test API Endpoints (Should Return "Not Configured")
|
|
|
|
```bash
|
|
# Test checkout endpoint
|
|
curl -X POST https://agenticgovernance.digital/api/koha/checkout \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"amount": 1500,
|
|
"currency": "NZD",
|
|
"frequency": "monthly",
|
|
"tier": "15",
|
|
"donor": {
|
|
"email": "test@example.com"
|
|
}
|
|
}'
|
|
```
|
|
|
|
**Expected Response:**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Donation system not yet active",
|
|
"message": "The Koha donation system is currently being configured. Please check back soon."
|
|
}
|
|
```
|
|
|
|
### 7.2 Test Transparency Endpoint
|
|
|
|
```bash
|
|
curl https://agenticgovernance.digital/api/koha/transparency
|
|
```
|
|
|
|
**Expected Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"total_received": 0,
|
|
"monthly_supporters": 0,
|
|
"one_time_donations": 0,
|
|
"monthly_recurring_revenue": 0,
|
|
"allocation": {
|
|
"hosting": 0.30,
|
|
"development": 0.40,
|
|
"research": 0.20,
|
|
"community": 0.10
|
|
},
|
|
"recent_donors": [],
|
|
"last_updated": "2025-10-08T..."
|
|
}
|
|
}
|
|
```
|
|
|
|
### 7.3 Test Frontend Pages Show Overlay
|
|
|
|
```bash
|
|
# Visit in browser:
|
|
https://agenticgovernance.digital/koha.html
|
|
https://agenticgovernance.digital/koha/transparency
|
|
https://agenticgovernance.digital/koha/success
|
|
```
|
|
|
|
**Expected:** All pages show "Coming Soon" overlay
|
|
|
|
### 7.4 Test Privacy Policy Accessible
|
|
|
|
```bash
|
|
curl -I https://agenticgovernance.digital/privacy.html
|
|
```
|
|
|
|
**Expected:** 200 OK (no overlay on privacy policy)
|
|
|
|
---
|
|
|
|
## Phase 8: Documentation Updates
|
|
|
|
### 8.1 Update Main README
|
|
|
|
Add to production README:
|
|
|
|
```markdown
|
|
## Koha Donation System Status
|
|
|
|
**Status:** Infrastructure Deployed (Awaiting Payment Integration)
|
|
**Location:** /koha.html, /koha/transparency, /koha/success
|
|
**Database:** koha_donations collection initialized
|
|
**Payment Processor:** Stripe (configuration pending)
|
|
|
|
The Koha donation system infrastructure is deployed but not yet publicly accessible.
|
|
Payment processing integration will be activated next week.
|
|
```
|
|
|
|
### 8.2 Create Activation Checklist
|
|
|
|
Document at `/var/www/tractatus/docs/KOHA_ACTIVATION_CHECKLIST.md`:
|
|
|
|
```markdown
|
|
# Koha Activation Checklist
|
|
|
|
When Stripe keys are ready:
|
|
|
|
1. [ ] Update .env with live Stripe keys
|
|
2. [ ] Create Stripe products and prices with currency_options
|
|
3. [ ] Set up production webhook endpoint
|
|
4. [ ] Remove coming-soon-overlay.js script tags
|
|
5. [ ] Remove PLACEHOLDER checks from koha.controller.js
|
|
6. [ ] Add navigation links to Koha pages
|
|
7. [ ] Test with Stripe test cards
|
|
8. [ ] Verify webhook delivery
|
|
9. [ ] Test end-to-end donation flow
|
|
10. [ ] Restart production server
|
|
11. [ ] Monitor first 24 hours of donations
|
|
12. [ ] Announce launch
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 9: Verification Checklist
|
|
|
|
Run through this checklist to verify deployment:
|
|
|
|
### Backend Verification
|
|
|
|
- [ ] Database collection `koha_donations` exists with 10 indexes
|
|
- [ ] Environment variables set (with PLACEHOLDER values)
|
|
- [ ] Koha service loads without errors
|
|
- [ ] Koha controller loads without errors
|
|
- [ ] Koha routes registered in Express
|
|
- [ ] API returns 503 "not configured" for checkout requests
|
|
- [ ] Transparency API returns empty data structure
|
|
- [ ] Server logs show no Koha-related errors
|
|
|
|
### Frontend Verification
|
|
|
|
- [ ] koha.html deployed and accessible (with overlay)
|
|
- [ ] koha/transparency.html deployed (with overlay)
|
|
- [ ] koha/success.html deployed (with overlay)
|
|
- [ ] privacy.html deployed and accessible (no overlay)
|
|
- [ ] Currency selector JS loaded
|
|
- [ ] Footer component JS loaded
|
|
- [ ] Coming soon overlay displays correctly
|
|
- [ ] Return to homepage link works
|
|
|
|
### Security Verification
|
|
|
|
- [ ] No live Stripe keys in .env
|
|
- [ ] No public navigation links to Koha pages
|
|
- [ ] Checkout endpoint protected with configuration check
|
|
- [ ] No sensitive data in error messages
|
|
- [ ] HTTPS enabled for all Koha URLs
|
|
|
|
---
|
|
|
|
## Rollback Plan
|
|
|
|
If issues occur, rollback steps:
|
|
|
|
```bash
|
|
# 1. Remove coming-soon-overlay.js from pages
|
|
# 2. Disable Koha routes in src/routes/index.js
|
|
# 3. Restart server
|
|
sudo systemctl restart tractatus
|
|
|
|
# 4. Drop koha_donations collection if needed
|
|
mongosh tractatus_prod --eval "db.koha_donations.drop()"
|
|
```
|
|
|
|
---
|
|
|
|
## Next Week: Stripe Activation
|
|
|
|
When live Stripe keys are ready:
|
|
|
|
1. Run `docs/KOHA_STRIPE_SETUP.md` (sections 1-7)
|
|
2. Update production .env with real keys
|
|
3. Remove overlay script tags from HTML files
|
|
4. Remove PLACEHOLDER checks from controller
|
|
5. Add navigation links to Koha pages
|
|
6. Restart server
|
|
7. Test end-to-end
|
|
|
|
**Estimated Time:** 2-3 hours
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
**Issues:** Check `/var/log/tractatus/` logs
|
|
**Questions:** john.stroh.nz@pm.me
|
|
**Documentation:** /docs/KOHA_STRIPE_SETUP.md
|
|
|
|
---
|
|
|
|
**Last Updated:** 2025-10-08
|
|
**Status:** Ready for pre-Stripe deployment
|
|
**Next Action:** Execute Phases 1-9 on production server
|