- 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>
282 lines
7.4 KiB
Markdown
282 lines
7.4 KiB
Markdown
# Phase 3: Project Context Awareness - Quick Reference
|
|
|
|
**Status**: PLANNING → READY TO START
|
|
**Estimated Duration**: 3-4 sessions (12-16 hours)
|
|
|
|
---
|
|
|
|
## 🎯 Goal
|
|
|
|
Transform Tractatus from **single-project** to **multi-project** governance system with context-aware variable substitution.
|
|
|
|
---
|
|
|
|
## 📊 Architecture at a Glance
|
|
|
|
```
|
|
USER ACTION: SYSTEM RESPONSE:
|
|
┌─────────────────┐ ┌────────────────────────────────┐
|
|
│ Select Project │ │ 1. Load applicable rules │
|
|
│ "tractatus" │──────────>│ 2. Fetch variable values │
|
|
└─────────────────┘ │ 3. Substitute ${VAR} → value │
|
|
│ 4. Display rendered text │
|
|
└────────────────────────────────┘
|
|
|
|
BEFORE (Template):
|
|
"MongoDB database MUST be named ${DB_NAME} in ${ENVIRONMENT}"
|
|
|
|
AFTER (Rendered for "tractatus"):
|
|
"MongoDB database MUST be named tractatus_dev in development"
|
|
|
|
AFTER (Rendered for "family-history"):
|
|
"MongoDB database MUST be named family_history in production"
|
|
```
|
|
|
|
---
|
|
|
|
## 🏗️ What We're Building
|
|
|
|
### Backend (Session 1-2)
|
|
|
|
#### Models
|
|
- ✅ **Project** - Store project metadata (id, name, tech stack)
|
|
- ✅ **VariableValue** - Store variable values per project
|
|
|
|
#### Services
|
|
- ✅ **VariableSubstitution** - Replace `${VAR}` with actual values
|
|
|
|
#### APIs
|
|
- ✅ **Projects API** - CRUD for projects
|
|
- ✅ **Variables API** - CRUD for variable values
|
|
- ✅ **Enhanced Rules API** - Return rules with substituted values
|
|
|
|
### Frontend (Session 3)
|
|
|
|
#### Components
|
|
- ✅ **Project Selector** - Dropdown in navbar
|
|
- ✅ **Project Manager** - Table view of all projects
|
|
- ✅ **Project Editor** - Form for project details + variable values
|
|
- ✅ **Variable Editor** - Modal for editing individual variables
|
|
|
|
#### Enhancements
|
|
- ✅ **Rule Manager** - Show rendered text for selected project
|
|
|
|
---
|
|
|
|
## 📋 Task Breakdown (4 Sessions)
|
|
|
|
### Session 1: Backend Foundation (3-4 hours)
|
|
```
|
|
1. Create Project.model.js
|
|
2. Create VariableValue.model.js
|
|
3. Create VariableSubstitution.service.js
|
|
4. Write unit tests for substitution logic
|
|
```
|
|
|
|
### Session 2: Backend APIs (3-4 hours)
|
|
```
|
|
5. Create projects.controller.js + routes
|
|
6. Create variables.controller.js + routes
|
|
7. Enhance rules.controller.js (add project context)
|
|
8. Write API integration tests
|
|
```
|
|
|
|
### Session 3: Frontend UI (4-5 hours)
|
|
```
|
|
9. Create project-manager.html
|
|
10. Create project-editor.js
|
|
11. Create project-selector.js component
|
|
12. Enhance rule-manager.js (show rendered text)
|
|
13. Create variable-editor.js modal
|
|
```
|
|
|
|
### Session 4: Testing & Docs (2-3 hours)
|
|
```
|
|
14. Create seed-projects.js (sample data)
|
|
15. Frontend integration testing
|
|
16. Write docs/api/PROJECTS_API.md
|
|
17. Write docs/USER_GUIDE_PROJECTS.md
|
|
```
|
|
|
|
---
|
|
|
|
## 🔑 Key Features
|
|
|
|
### 1. Variable Substitution
|
|
```javascript
|
|
// Template Rule
|
|
text: "Use port ${APP_PORT} for ${APP_NAME}"
|
|
variables: ["APP_PORT", "APP_NAME"]
|
|
|
|
// Project: tractatus
|
|
variables: {
|
|
APP_PORT: "9000",
|
|
APP_NAME: "Tractatus"
|
|
}
|
|
|
|
// Rendered
|
|
"Use port 9000 for Tractatus"
|
|
```
|
|
|
|
### 2. Project Filtering
|
|
```javascript
|
|
// Rule with scope
|
|
{
|
|
scope: "PROJECT_SPECIFIC",
|
|
applicableProjects: ["tractatus", "family-history"]
|
|
}
|
|
|
|
// When project="tractatus" selected
|
|
// Show: UNIVERSAL rules + rules with "tractatus" in applicableProjects
|
|
```
|
|
|
|
### 3. Context-Aware Display
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ Rule Manager [Project: Tractatus ▼] │
|
|
├─────────────────────────────────────────────────┤
|
|
│ inst_019 | SYSTEM | HIGH │
|
|
│ │
|
|
│ Rendered (for Tractatus): │
|
|
│ MongoDB database MUST be named tractatus_dev │
|
|
│ │
|
|
│ Template: ...${DB_NAME}... │
|
|
│ Variables: DB_NAME=tractatus_dev │
|
|
└─────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 💾 Database Schema
|
|
|
|
### Project
|
|
```javascript
|
|
{
|
|
id: 'tractatus', // PK, unique
|
|
name: 'Tractatus Framework',
|
|
description: 'Agentic governance framework',
|
|
techStack: {
|
|
language: 'JavaScript',
|
|
framework: 'Node.js/Express',
|
|
database: 'MongoDB',
|
|
frontend: 'Vanilla JS'
|
|
},
|
|
active: true
|
|
}
|
|
```
|
|
|
|
### VariableValue
|
|
```javascript
|
|
{
|
|
projectId: 'tractatus', // FK to Project.id
|
|
variableName: 'DB_NAME', // Variable name
|
|
value: 'tractatus_dev', // Actual value
|
|
description: 'Development database name',
|
|
category: 'database' // database/config/path/url
|
|
}
|
|
```
|
|
|
|
**Compound Unique Index**: `(projectId, variableName)`
|
|
|
|
---
|
|
|
|
## 🔄 Data Flow Example
|
|
|
|
### Creating a Project with Variables
|
|
|
|
```bash
|
|
# 1. Create project
|
|
POST /api/admin/projects
|
|
{
|
|
"id": "tractatus",
|
|
"name": "Tractatus Framework",
|
|
"techStack": { "database": "MongoDB" }
|
|
}
|
|
|
|
# 2. Add variable values
|
|
POST /api/admin/projects/tractatus/variables
|
|
{
|
|
"variableName": "DB_NAME",
|
|
"value": "tractatus_dev",
|
|
"category": "database"
|
|
}
|
|
|
|
# 3. Get rules with substitution
|
|
GET /api/admin/rules?project=tractatus
|
|
|
|
# Response includes rendered text
|
|
{
|
|
"rules": [{
|
|
"id": "inst_019",
|
|
"text": "...${DB_NAME}...",
|
|
"renderedText": "...tractatus_dev...",
|
|
"variables": [{"name": "DB_NAME", "value": "tractatus_dev"}]
|
|
}]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ✅ Success Criteria
|
|
|
|
### Functional
|
|
- ✅ Create/edit/delete projects
|
|
- ✅ Set variable values per project
|
|
- ✅ View rules with substituted values
|
|
- ✅ Switch between projects
|
|
- ✅ Detect missing variables
|
|
|
|
### Technical
|
|
- ✅ Substitution performance < 50ms
|
|
- ✅ All APIs tested (integration)
|
|
- ✅ Frontend components functional
|
|
- ✅ Database indexes optimized
|
|
|
|
### UX
|
|
- ✅ Intuitive project switching
|
|
- ✅ Clear template vs rendered distinction
|
|
- ✅ Easy variable editing
|
|
- ✅ Helpful error messages
|
|
|
|
---
|
|
|
|
## 🚀 Getting Started
|
|
|
|
### Session 1 Tasks
|
|
1. Create `src/models/Project.model.js`
|
|
2. Create `src/models/VariableValue.model.js`
|
|
3. Create `src/services/VariableSubstitution.service.js`
|
|
4. Write tests: `tests/unit/VariableSubstitution.test.js`
|
|
|
|
**Start Command**:
|
|
```bash
|
|
# Create model files
|
|
touch src/models/Project.model.js
|
|
touch src/models/VariableValue.model.js
|
|
touch src/services/VariableSubstitution.service.js
|
|
touch tests/unit/VariableSubstitution.test.js
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Reference Documents
|
|
|
|
- **Full Plan**: `docs/planning/PHASE_3_PROJECT_CONTEXT_PLAN.md`
|
|
- **Phase 1 Complete**: `docs/USER_GUIDE_RULE_MANAGER.md`
|
|
- **Phase 2 Complete**: `docs/testing/PHASE_2_TEST_RESULTS.md`
|
|
- **Coding Best Practices**: `docs/governance/CODING_BEST_PRACTICES_SUMMARY.md`
|
|
|
|
---
|
|
|
|
## 🎯 Next Actions
|
|
|
|
**Ready to start?** Say:
|
|
- "Start Phase 3 Session 1" - Begin backend foundation
|
|
- "Show me the full plan" - Review detailed plan
|
|
- "Modify the plan" - Adjust scope or approach
|
|
|
|
---
|
|
|
|
**Plan Status**: ✅ APPROVED - READY TO BUILD
|
|
**Est. Completion**: 3-4 sessions from now
|
|
**Dependencies**: None (Phase 1 & 2 complete)
|