- 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>
603 lines
18 KiB
Markdown
603 lines
18 KiB
Markdown
# Document Optimization Workflow
|
|
|
|
**Purpose:** Process all 37 user-facing documents for inst_039 compliance, accuracy, and professional presentation.
|
|
|
|
**Last Updated:** 2025-10-13
|
|
|
|
---
|
|
|
|
## Pre-Approved Bash Commands for Workflow
|
|
|
|
**The following bash commands are PRE-APPROVED for use during document optimization:**
|
|
|
|
All commands in this workflow are designed for safety and have been approved in advance. Claude Code can execute these without interruption:
|
|
|
|
### Database Operations (Read-Only)
|
|
- `mongosh tractatus_dev --quiet --eval "db.documents.find(...)"` - Query documents
|
|
- `mongosh tractatus_dev --quiet --eval "db.documents.countDocuments()"` - Count documents
|
|
- `mongosh tractatus_dev --quiet --eval "print(...)"` - Display results
|
|
|
|
### Database Operations (Write - Approved Patterns)
|
|
- `mongosh tractatus_dev --quiet --eval "db.documents.updateOne({slug: 'X'}, {\$set: {slug: 'Y'}})"` - Fix slug mismatches
|
|
- `npm run migrate:docs -- --source docs/markdown --force` - Migrate markdown to database
|
|
|
|
### File Operations (Read-Only)
|
|
- `wc -w < file.md` - Count words
|
|
- `basename file.md .md` - Extract filename without extension
|
|
- `[ -f file ] && echo "exists"` - Check file existence
|
|
- `ls -lh file` - Check file size
|
|
- `grep -q "pattern" file` - Search for patterns
|
|
|
|
### Script Executions
|
|
- `node scripts/generate-card-sections.js file.md --update-db` - Generate card sections
|
|
- `node scripts/generate-single-pdf.js input.md output.pdf` - Generate PDFs
|
|
- `timeout 90 node scripts/...` - Run scripts with timeout protection
|
|
|
|
### Validation Commands
|
|
- `curl -s http://localhost:9000/api/documents/slug` - Test API endpoints
|
|
- `curl -s -I http://localhost:9000/downloads/file.pdf | grep "200 OK"` - Test PDF access
|
|
- `lsof -i :9000` - Check if dev server running
|
|
|
|
### Production Operations (Approved Patterns)
|
|
- `printf "yes\nyes\n" | ./scripts/deploy-full-project-SAFE.sh` - Deploy with confirmations
|
|
- `ssh -i ~/.ssh/tractatus_deploy ubuntu@host "command"` - Execute on production
|
|
- `rsync -avz -e "ssh -i key" source dest` - Sync files to production
|
|
|
|
**Note:** These commands are designed to be non-destructive and follow the principle of least privilege. They:
|
|
- Read before writing
|
|
- Validate before executing
|
|
- Provide clear output
|
|
- Fail safely if errors occur
|
|
- Never delete or drop without explicit backups
|
|
|
|
---
|
|
|
|
## Prerequisites Checklist
|
|
|
|
Before starting ANY document processing, verify:
|
|
|
|
```bash
|
|
# 1. Environment files exist and are valid
|
|
[ -f .env ] && echo "✅ .env exists" || echo "❌ Missing .env"
|
|
|
|
# 2. Database connections work (both dev and prod)
|
|
mongosh tractatus_dev --quiet --eval "db.documents.countDocuments()" && echo "✅ Dev DB accessible"
|
|
|
|
# 3. Required scripts have dotenv loaded
|
|
grep -q "require('dotenv')" scripts/generate-card-sections.js && echo "✅ Card script has dotenv"
|
|
grep -q "require('dotenv')" scripts/generate-single-pdf.js && echo "✅ PDF script has dotenv"
|
|
|
|
# 4. Dev server is NOT running (prevents port conflicts)
|
|
lsof -i :9000 && echo "⚠️ Server running - may cause issues" || echo "✅ Port 9000 free"
|
|
```
|
|
|
|
---
|
|
|
|
## Single Document Workflow
|
|
|
|
**For each document:**
|
|
|
|
### Step 1: Pre-Flight Checks
|
|
|
|
```bash
|
|
# Set variables (IMPORTANT: slug must match filename case exactly)
|
|
DOC_FILE="docs/markdown/core-concepts.md"
|
|
DOC_SLUG=$(basename "$DOC_FILE" .md) # Extract slug from filename (preserves case)
|
|
|
|
echo "=== PRE-FLIGHT CHECKS ==="
|
|
echo "File: $DOC_FILE"
|
|
echo "Slug: $DOC_SLUG"
|
|
echo ""
|
|
|
|
# Verify file exists
|
|
if [ -f "$DOC_FILE" ]; then
|
|
echo "✅ File exists"
|
|
else
|
|
echo "❌ File not found"
|
|
exit 1
|
|
fi
|
|
|
|
# Check file size (large documents take longer)
|
|
WORD_COUNT=$(wc -w < "$DOC_FILE")
|
|
if [ "$WORD_COUNT" -gt 5000 ]; then
|
|
echo "⚠️ Large document ($WORD_COUNT words) - processing may take longer"
|
|
else
|
|
echo "✅ Document size: $WORD_COUNT words"
|
|
fi
|
|
|
|
# .env exists
|
|
[ -f .env ] && echo "✅ .env exists" || echo "❌ Missing .env"
|
|
|
|
# Dev DB accessible
|
|
if mongosh tractatus_dev --quiet --eval "db.documents.countDocuments()" >/dev/null 2>&1; then
|
|
DOC_COUNT=$(mongosh tractatus_dev --quiet --eval "print(db.documents.countDocuments())")
|
|
echo "✅ Dev DB accessible: $DOC_COUNT documents"
|
|
else
|
|
echo "❌ Dev DB not accessible"
|
|
fi
|
|
|
|
# Scripts have dotenv
|
|
grep -q "require('dotenv')" scripts/generate-card-sections.js && echo "✅ Card script has dotenv" || echo "❌ Card script missing dotenv"
|
|
|
|
# Port 9000 status
|
|
if lsof -i :9000 >/dev/null 2>&1; then
|
|
echo "⚠️ Port 9000 in use (dev server running)"
|
|
else
|
|
echo "✅ Port 9000 free"
|
|
fi
|
|
|
|
# Check document status in DB
|
|
echo ""
|
|
echo "=== DATABASE STATUS ==="
|
|
mongosh tractatus_dev --quiet --eval "
|
|
const doc = db.documents.findOne({slug: '$DOC_SLUG'});
|
|
if (!doc) {
|
|
print('⚠️ Document not in DB yet - will be created by migration');
|
|
} else {
|
|
print('✅ Document exists: ' + doc.title);
|
|
print(' Slug: ' + doc.slug);
|
|
print(' Sections: ' + (doc.sections ? doc.sections.length : 0));
|
|
}
|
|
"
|
|
```
|
|
|
|
### Step 2: Content Review and Edits
|
|
|
|
```bash
|
|
# Run pre-action governance check
|
|
node scripts/pre-action-check.js file-edit "$DOC_FILE" "Optimize for inst_039, accuracy, metadata"
|
|
|
|
# Manual review (Claude reads file and identifies issues):
|
|
# - inst_039 violations
|
|
# - ContextPressureMonitor weights (must be 40%/30%/15%/10%/5%)
|
|
# - Missing license section (Apache 2.0 required)
|
|
# - Missing metadata section
|
|
# - Factual inaccuracies about 6 services
|
|
|
|
# Apply edits to markdown file
|
|
# (Claude uses Edit tool for each change)
|
|
```
|
|
|
|
### Step 3: Database Pipeline (Dev)
|
|
|
|
```bash
|
|
echo ""
|
|
echo "=== DATABASE PIPELINE ==="
|
|
|
|
# 3a. Migrate to database (creates/updates document)
|
|
echo "Step 3a: Migrating to database..."
|
|
npm run migrate:docs -- --source docs/markdown --force 2>&1 | grep -E "($(basename $DOC_FILE)|Total|Summary)" || echo "Migration completed"
|
|
|
|
# 3b. Check and fix slug if needed
|
|
echo ""
|
|
echo "Step 3b: Verifying slug..."
|
|
ACTUAL_SLUG=$(mongosh tractatus_dev --quiet --eval "
|
|
const doc = db.documents.findOne({title: /$(basename $DOC_FILE .md | sed 's/-/ /g')/i});
|
|
print(doc ? doc.slug : 'NOT_FOUND');
|
|
")
|
|
|
|
echo "Expected slug: $DOC_SLUG"
|
|
echo "Actual slug: $ACTUAL_SLUG"
|
|
|
|
if [ "$ACTUAL_SLUG" != "$DOC_SLUG" ] && [ "$ACTUAL_SLUG" != "NOT_FOUND" ]; then
|
|
echo "⚠️ Fixing slug: $ACTUAL_SLUG → $DOC_SLUG"
|
|
mongosh tractatus_dev --quiet --eval "
|
|
db.documents.updateOne(
|
|
{slug: '$ACTUAL_SLUG'},
|
|
{\$set: {slug: '$DOC_SLUG'}}
|
|
)
|
|
"
|
|
echo "✅ Slug fixed"
|
|
else
|
|
echo "✅ Slug matches"
|
|
fi
|
|
|
|
# 3c. Generate and update card sections
|
|
echo ""
|
|
echo "Step 3c: Generating card sections..."
|
|
echo "⚠️ This may timeout but succeed - validation will confirm"
|
|
|
|
# Run with timeout, but don't fail on timeout
|
|
timeout 90 node scripts/generate-card-sections.js "$DOC_FILE" --update-db || echo "⚠️ Command timed out (checking validation...)"
|
|
|
|
# Verify sections were created (regardless of timeout)
|
|
sleep 2
|
|
SECTION_COUNT=$(mongosh tractatus_dev --quiet --eval "
|
|
const doc = db.documents.findOne({slug: '$DOC_SLUG'});
|
|
print(doc.sections ? doc.sections.length : 0);
|
|
")
|
|
|
|
if [ "$SECTION_COUNT" -gt 0 ]; then
|
|
echo "✅ Card sections created: $SECTION_COUNT sections"
|
|
else
|
|
echo "❌ Card sections not created - retrying..."
|
|
node scripts/generate-card-sections.js "$DOC_FILE" --update-db
|
|
fi
|
|
|
|
# 3d. Generate PDF
|
|
echo ""
|
|
echo "Step 3d: Generating PDF..."
|
|
PDF_OUTPUT="public/downloads/$DOC_SLUG.pdf"
|
|
node scripts/generate-single-pdf.js "$DOC_FILE" "$PDF_OUTPUT"
|
|
|
|
if [ -f "$PDF_OUTPUT" ]; then
|
|
PDF_SIZE=$(ls -lh "$PDF_OUTPUT" | awk '{print $5}')
|
|
echo "✅ PDF created: $PDF_SIZE"
|
|
else
|
|
echo "❌ PDF generation failed"
|
|
exit 1
|
|
fi
|
|
```
|
|
|
|
### Step 4: Validation (Dev)
|
|
|
|
```bash
|
|
# Start dev server if not running
|
|
npm start &
|
|
DEV_PID=$!
|
|
sleep 3
|
|
|
|
# Validate document API response
|
|
curl -s "http://localhost:9000/api/documents/$DOC_SLUG" | \
|
|
node -e "
|
|
const data = require('fs').readFileSync(0, 'utf8');
|
|
const resp = JSON.parse(data);
|
|
const doc = resp.document;
|
|
|
|
console.log('Title:', doc.title);
|
|
console.log('Sections:', doc.sections?.length || 0);
|
|
console.log('Has License:', doc.sections?.find(s => s.title === 'License') ? 'YES' : 'NO');
|
|
console.log('Has Metadata:', doc.sections?.find(s => s.title === 'Document Metadata') ? 'YES' : 'NO');
|
|
|
|
if (!doc.sections || doc.sections.length < 5) {
|
|
console.error('❌ VALIDATION FAILED: Too few sections');
|
|
process.exit(1);
|
|
}
|
|
"
|
|
|
|
# Validate PDF accessible
|
|
curl -s -I "http://localhost:9000/downloads/$DOC_SLUG.pdf" | grep -q "200 OK" || {
|
|
echo "❌ PDF not accessible"
|
|
exit 1
|
|
}
|
|
|
|
echo "✅ Dev validation passed"
|
|
|
|
# Stop dev server
|
|
kill $DEV_PID
|
|
```
|
|
|
|
---
|
|
|
|
## Batch Deployment (Per Category)
|
|
|
|
**After completing ALL documents in a category:**
|
|
|
|
### Step 5: Deploy to Production
|
|
|
|
```bash
|
|
# Deploy all files
|
|
printf "yes\nyes\n" | ./scripts/deploy-full-project-SAFE.sh
|
|
|
|
# Restart production server
|
|
ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net \
|
|
'sudo systemctl restart tractatus'
|
|
|
|
# Wait for restart
|
|
sleep 5
|
|
|
|
# Migrate documents on production
|
|
ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net \
|
|
'cd /var/www/tractatus && npm run migrate:docs -- --source docs/markdown --force'
|
|
```
|
|
|
|
### Step 6: Fix Slugs on Production (if needed)
|
|
|
|
```bash
|
|
# For each document in the category, check and fix slugs if needed:
|
|
for DOC_FILE in docs/markdown/introduction-to-the-tractatus-framework.md docs/markdown/core-concepts.md docs/markdown/GLOSSARY.md; do
|
|
DOC_SLUG=$(basename "$DOC_FILE" .md)
|
|
|
|
echo "Checking slug for: $DOC_SLUG"
|
|
|
|
# Get actual slug from production
|
|
ACTUAL_SLUG=$(ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net \
|
|
"mongosh tractatus_prod --quiet -u tractatus_user -p 'uV6IajYK7pdrqY1uGad/K/LwDIaL7pebLZApPqS1FjE=' \
|
|
--authenticationDatabase tractatus_prod \
|
|
--eval \"const doc = db.documents.findOne({title: /$DOC_SLUG/i}); print(doc ? doc.slug : 'NOT_FOUND');\""
|
|
)
|
|
|
|
if [ "$ACTUAL_SLUG" != "$DOC_SLUG" ] && [ "$ACTUAL_SLUG" != "NOT_FOUND" ]; then
|
|
echo "⚠️ Fixing slug on production: $ACTUAL_SLUG → $DOC_SLUG"
|
|
|
|
ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net \
|
|
"mongosh tractatus_prod --quiet -u tractatus_user -p 'uV6IajYK7pdrqY1uGad/K/LwDIaL7pebLZApPqS1FjE=' \
|
|
--authenticationDatabase tractatus_prod \
|
|
--eval \"db.documents.updateOne({slug: '$ACTUAL_SLUG'}, {\\\$set: {slug: '$DOC_SLUG'}})\""
|
|
|
|
echo "✅ Slug fixed on production"
|
|
else
|
|
echo "✅ Slug matches: $DOC_SLUG"
|
|
fi
|
|
echo ""
|
|
done
|
|
```
|
|
|
|
### Step 7: Generate Card Sections on Production
|
|
|
|
**NOTE:** This step often times out but succeeds. Check results, don't retry unnecessarily.
|
|
|
|
```bash
|
|
# For each document in the category:
|
|
for DOC_FILE in docs/markdown/introduction-to-the-tractatus-framework.md docs/markdown/core-concepts.md; do
|
|
DOC_SLUG=$(basename "$DOC_FILE" .md)
|
|
|
|
echo "Processing $DOC_SLUG on production..."
|
|
|
|
# Run card generation (may timeout but succeed)
|
|
ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net \
|
|
"cd /var/www/tractatus && timeout 90 node scripts/generate-card-sections.js docs/markdown/$(basename $DOC_FILE) --update-db" \
|
|
|| echo "⚠️ Timed out (may have succeeded)"
|
|
done
|
|
```
|
|
|
|
### Step 8: Validation (Production)
|
|
|
|
```bash
|
|
# For each document in category:
|
|
for DOC_SLUG in introduction-to-the-tractatus-framework core-concepts; do
|
|
echo "=== Validating: $DOC_SLUG ==="
|
|
|
|
# Validate API response
|
|
curl -s "https://agenticgovernance.digital/api/documents/$DOC_SLUG" | \
|
|
node -e "
|
|
const data = require('fs').readFileSync(0, 'utf8');
|
|
const resp = JSON.parse(data);
|
|
const doc = resp.document;
|
|
|
|
console.log(' Title:', doc.title);
|
|
console.log(' Sections:', doc.sections?.length || 0);
|
|
console.log(' License:', doc.sections?.find(s => s.title === 'License') ? 'YES' : 'NO');
|
|
console.log(' Metadata:', doc.sections?.find(s => s.title === 'Document Metadata') ? 'YES' : 'NO');
|
|
|
|
if (!doc.sections || doc.sections.length < 5) {
|
|
console.error(' ❌ FAILED: Too few sections');
|
|
process.exit(1);
|
|
}
|
|
"
|
|
|
|
# Validate PDF
|
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://agenticgovernance.digital/downloads/$DOC_SLUG.pdf")
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
echo " ✅ PDF accessible"
|
|
else
|
|
echo " ❌ PDF not accessible (HTTP $HTTP_CODE)"
|
|
fi
|
|
|
|
echo ""
|
|
done
|
|
|
|
echo "✅ Production validation complete"
|
|
```
|
|
|
|
---
|
|
|
|
## Common Issues and Solutions
|
|
|
|
### Issue: "Document not found: [slug]"
|
|
|
|
**Cause:** Slug mismatch between filename and database
|
|
**Solution:**
|
|
```bash
|
|
# Find actual slug in DB
|
|
mongosh tractatus_dev --quiet --eval "db.documents.find({title: /your title/i}, {slug: 1, title: 1}).pretty()"
|
|
|
|
# Update to match filename
|
|
mongosh tractatus_dev --quiet --eval "db.documents.updateOne({slug: 'wrong-slug'}, {\$set: {slug: 'correct-slug'}})"
|
|
```
|
|
|
|
### Issue: "Command find requires authentication"
|
|
|
|
**Cause:** Script not loading `.env` file
|
|
**Solution:** Add to top of script:
|
|
```javascript
|
|
require('dotenv').config();
|
|
```
|
|
|
|
### Issue: Card generation times out on production
|
|
|
|
**Cause:** MongoDB connection slowness, but operation likely succeeds
|
|
**Solution:**
|
|
- Don't retry immediately
|
|
- Check validation instead: `curl https://agenticgovernance.digital/api/documents/[slug]`
|
|
- If sections exist, operation succeeded despite timeout
|
|
|
|
### Issue: PDF not accessible
|
|
|
|
**Cause:** PDF not generated or not deployed
|
|
**Solution:**
|
|
```bash
|
|
# Check if PDF exists locally
|
|
ls -lh public/downloads/[slug].pdf
|
|
|
|
# If missing, regenerate
|
|
node scripts/generate-single-pdf.js docs/markdown/[file].md public/downloads/[slug].pdf
|
|
|
|
# Redeploy
|
|
rsync -avz -e "ssh -i ~/.ssh/tractatus_deploy" public/downloads/[slug].pdf \
|
|
ubuntu@vps-93a693da.vps.ovh.net:/var/www/tractatus/public/downloads/
|
|
```
|
|
|
|
---
|
|
|
|
## Workflow Optimization Script (Future)
|
|
|
|
**TODO:** Create `scripts/process-document.sh` that combines all steps:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Usage: ./scripts/process-document.sh docs/markdown/core-concepts.md
|
|
|
|
# Would automate:
|
|
# 1. Pre-flight checks
|
|
# 2. Migration
|
|
# 3. Slug verification/fix
|
|
# 4. Card generation
|
|
# 5. PDF generation
|
|
# 6. Local validation
|
|
# Exit code 0 = success, 1 = failure
|
|
|
|
# Then batch script for categories:
|
|
# ./scripts/process-category.sh "getting-started" "introduction*.md" "core-concepts.md"
|
|
```
|
|
|
|
---
|
|
|
|
## Category Processing Order
|
|
|
|
1. ✅ **Getting Started** (2 docs) - COMPLETED
|
|
2. **Technical Reference** (10 docs)
|
|
3. **Theory & Research** (5 docs)
|
|
4. **Advanced Topics** (6 docs)
|
|
5. **Case Studies** (6 docs)
|
|
6. **Business & Leadership** (2 docs)
|
|
|
|
**Estimated time per document:**
|
|
- Small documents (<5,000 words): 10-12 minutes
|
|
- Large documents (>5,000 words): 13-18 minutes
|
|
- Previous ad-hoc approach: 30-45 minutes
|
|
- **Time savings: 50-70% reduction**
|
|
|
|
---
|
|
|
|
## Document Template Standards
|
|
|
|
### License Section (Required)
|
|
|
|
```markdown
|
|
## License
|
|
|
|
Copyright 2025 John Stroh
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
|
|
**Summary:**
|
|
- ✅ Commercial use allowed
|
|
- ✅ Modification allowed
|
|
- ✅ Distribution allowed
|
|
- ✅ Patent grant included
|
|
- ✅ Private use allowed
|
|
- ⚠️ Must include license and copyright notice
|
|
- ⚠️ Must state significant changes
|
|
- ❌ No trademark rights granted
|
|
- ❌ No liability or warranty
|
|
```
|
|
|
|
### Metadata Section (Required)
|
|
|
|
```markdown
|
|
## Document Metadata
|
|
|
|
<div class="document-metadata">
|
|
|
|
- **Version:** 0.5.0
|
|
- **Created:** [YYYY-MM-DD]
|
|
- **Last Modified:** [YYYY-MM-DD]
|
|
- **Author:** John Stroh
|
|
- **Word Count:** [calculated] words
|
|
- **Reading Time:** ~[calculated] minutes
|
|
- **Document ID:** [slug]
|
|
- **Status:** Active
|
|
|
|
</div>
|
|
```
|
|
|
|
### ContextPressureMonitor Weights (If mentioned)
|
|
|
|
**MUST use current weights (as of 2025-10-12):**
|
|
- Conversation length: 40% (PRIMARY)
|
|
- Token usage: 30%
|
|
- Task complexity: 15%
|
|
- Error frequency: 10%
|
|
- Instruction density: 5%
|
|
|
|
---
|
|
|
|
## Validation Checklist Per Document
|
|
|
|
- [ ] inst_039 compliance (no "guarantees", "ensures", etc.)
|
|
- [ ] ContextPressureMonitor weights correct (40/30/15/10/5)
|
|
- [ ] All 6 services mentioned accurately
|
|
- [ ] License section present (Apache 2.0)
|
|
- [ ] Metadata section present
|
|
- [ ] Card sections generated (>5 sections)
|
|
- [ ] PDF accessible on dev
|
|
- [ ] PDF accessible on production
|
|
- [ ] Viewable in side panel on production
|
|
|
|
---
|
|
|
|
## Quick Reference: Copy-Paste Commands
|
|
|
|
### Single Document Processing (Complete Pipeline)
|
|
|
|
```bash
|
|
# 1. Set document
|
|
DOC_FILE="docs/markdown/your-document.md"
|
|
DOC_SLUG=$(basename "$DOC_FILE" .md)
|
|
|
|
# 2. Pre-flight checks
|
|
echo "=== PRE-FLIGHT CHECKS ==="
|
|
[ -f "$DOC_FILE" ] && echo "✅ File exists" || exit 1
|
|
WORD_COUNT=$(wc -w < "$DOC_FILE")
|
|
echo "Document size: $WORD_COUNT words"
|
|
|
|
# 3. Database pipeline
|
|
npm run migrate:docs -- --source docs/markdown --force
|
|
mongosh tractatus_dev --quiet --eval "db.documents.updateOne({title: /your title/i}, {\$set: {slug: '$DOC_SLUG'}})"
|
|
timeout 90 node scripts/generate-card-sections.js "$DOC_FILE" --update-db || echo "Timeout (validating...)"
|
|
node scripts/generate-single-pdf.js "$DOC_FILE" "public/downloads/$DOC_SLUG.pdf"
|
|
|
|
# 4. Validation
|
|
curl -s "http://localhost:9000/api/documents/$DOC_SLUG" | node -e "const d=JSON.parse(require('fs').readFileSync(0,'utf8')).document; console.log('Sections:', d.sections?.length)"
|
|
curl -s -I "http://localhost:9000/downloads/$DOC_SLUG.pdf" | grep -q "200 OK" && echo "✅ PDF accessible"
|
|
```
|
|
|
|
### Category Deployment (After All Docs Complete)
|
|
|
|
```bash
|
|
# Deploy to production
|
|
printf "yes\nyes\n" | ./scripts/deploy-full-project-SAFE.sh
|
|
|
|
# Restart and migrate
|
|
ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net 'sudo systemctl restart tractatus && cd /var/www/tractatus && npm run migrate:docs -- --source docs/markdown --force'
|
|
|
|
# Validate on production
|
|
curl -s "https://agenticgovernance.digital/api/documents/$DOC_SLUG" | node -e "const d=JSON.parse(require('fs').readFileSync(0,'utf8')).document; console.log('✅ Sections:', d.sections?.length)"
|
|
```
|
|
|
|
### Common Troubleshooting
|
|
|
|
```bash
|
|
# Fix slug mismatch
|
|
mongosh tractatus_dev --quiet --eval "db.documents.updateOne({slug: 'wrong-slug'}, {\$set: {slug: 'correct-slug'}})"
|
|
|
|
# Check document status
|
|
mongosh tractatus_dev --quiet --eval "db.documents.findOne({slug: 'doc-slug'}, {title: 1, slug: 1, sections: 1})"
|
|
|
|
# Regenerate PDF
|
|
node scripts/generate-single-pdf.js docs/markdown/file.md public/downloads/slug.pdf
|
|
|
|
# Check PDF exists
|
|
ls -lh public/downloads/*.pdf | tail -5
|
|
```
|
|
|
|
---
|
|
|
|
**Maintained by:** Claude Code session governance
|
|
**Version:** 1.1
|
|
**Last Updated:** 2025-10-13
|