Skip to content

mstanton/NOS

Repository files navigation

Notion-OpenSpec Integration (NOS)

A comprehensive integration service that connects Notion with OpenSpec, enabling AI-powered specification management, validation, and collaboration workflows.

Overview

This service enables teams to create, manage, version, and collaborate on technical specifications directly within Notion, while leveraging OpenSpec's AI capabilities for intelligent spec generation, validation, and optimization.

Key Features

  • AI-Powered Specification Generation: Generate comprehensive specifications from minimal input using OpenSpec AI
  • Automated Validation: Validate specifications against organizational standards with detailed scoring and feedback
  • Version Control: Track all specification changes with complete audit trails and rollback capabilities
  • Collaborative Review Workflows: Enable team collaboration with structured review and approval processes
  • Notion Integration: Seamless two-way sync with Notion databases
  • RESTful API: Complete REST API for all operations with authentication and rate limiting

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Notion Workspace                         │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │  Database: Specifications                                  │ │
│  └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              ▲
                              │ Notion API (REST)
                              │
┌─────────────────────────────────────────────────────────────────┐
│                  NOS Integration Service                        │
│  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────┐   │
│  │  API Gateway     │  │  Validation      │  │  Version     │   │
│  │  (Express.js)    │  │  Engine          │  │  Manager     │   │
│  └──────────────────┘  └──────────────────┘  └──────────────┘   │
│  ┌──────────────────┐  ┌──────────────────┐                     │
│  │  Notion Adapter  │  │  OpenSpec Client │                     │
│  └──────────────────┘  └──────────────────┘                     │
└─────────────────────────────────────────────────────────────────┘
         ▲                              ▲
         │ Notion API                   │ OpenSpec API
         │                              │
    ┌────────────┐              ┌──────────────┐
    │   Notion   │              │   OpenSpec   │
    │   Cloud    │              │   Service    │
    └────────────┘              └──────────────┘

Technology Stack

  • Runtime: Node.js 20+
  • Language: TypeScript 5+
  • Framework: Express.js
  • API Integrations: Notion API, OpenSpec API
  • Caching (Optional): Redis
  • Database (Optional): PostgreSQL for audit logs
  • Containerization: Podman (rootless, daemonless) - Docker compatible
  • Testing: Jest

Getting Started

Prerequisites

  • Node.js 20+ and npm 10+
  • Podman (recommended) or Docker (for containerized deployment)
  • Notion workspace with API integration token
  • OpenSpec API credentials (optional - fallback validation available)

Installation

  1. Clone the repository

    git clone https://github.com/your-org/notion-openspec-integration.git
    cd notion-openspec-integration
  2. Install dependencies

    npm install
  3. Configure environment variables

    cp .env.example .env
    # Edit .env and add your API tokens and configuration
  4. Required Configuration

    • NOTION_API_TOKEN: Your Notion integration token
    • NOTION_DATABASE_ID: ID of your Notion specifications database
    • OPENSPEC_API_TOKEN: Your OpenSpec API token (optional)
    • JWT_SECRET: Secret key for JWT authentication (change in production!)

Running Locally

Development mode with auto-reload:

npm run dev

Build and run production:

npm run build
npm start

Run tests:

npm test

Run with coverage:

npm run test -- --coverage

Running with Podman (Recommended)

Podman provides enhanced security with:

  • Rootless containers: No daemon running as root
  • Daemonless architecture: Direct fork/exec model
  • Drop-in Docker replacement: Compatible with Docker commands
  • Better security: No single point of failure, reduced attack surface

Using Make commands (easiest):

# Check dependencies
make check-deps

# Build and start all services
make quick-start

# View logs
make logs

# Stop services
make down

# Restart everything
make quick-restart

# See all available commands
make help

Using podman-compose directly:

# Start all services
podman-compose up -d

# View logs
podman-compose logs -f app

# Stop services
podman-compose down

# Rebuild after code changes
podman-compose up -d --build

Using Podman directly (without compose):

# Build image
podman build -f Containerfile -t nos-integration:latest .

# Run container
podman run -d \
  --name nos-integration \
  -p 3000:3000 \
  --env-file .env \
  nos-integration:latest

# View logs
podman logs -f nos-integration

# Stop container
podman stop nos-integration

Running with Docker (Legacy)

If you prefer Docker over Podman:

# Use docker-compose.yml instead
docker-compose up -d
docker-compose logs -f app
docker-compose down

Note: Dockerfile is maintained for Docker compatibility, but Containerfile is recommended for Podman.

API Documentation

Base URL

http://localhost:3000/api/v1

Authentication

All endpoints (except /health and /health/*) require authentication via JWT token:

Authorization: Bearer <your_jwt_token>

Key Endpoints

Health Check

GET /health

Returns system health status including Notion API, OpenSpec API, and database connectivity.

Create Specification

POST /specifications
Content-Type: application/json
Authorization: Bearer <token>

{
  "title": "User Authentication Feature",
  "spec_type": "Feature",
  "overview": "Implement secure user authentication...",
  "priority": "P0",
  "tags": ["security", "authentication"]
}

Generate Specification with AI

POST /specifications/generate
Content-Type: application/json
Authorization: Bearer <token>

{
  "feature_overview": "We need a user authentication system that supports email/password and OAuth providers...",
  "goals": ["Secure authentication", "Social login support"],
  "constraints": ["Must comply with GDPR"],
  "spec_type": "Feature"
}

Validate Specification

POST /specifications/:spec_id/validate
Content-Type: application/json
Authorization: Bearer <token>

{
  "ignore_cache": false
}

Get Specification

GET /specifications/:spec_id
Authorization: Bearer <token>

Update Specification

PUT /specifications/:spec_id
Content-Type: application/json
Authorization: Bearer <token>

{
  "title": "Updated Title",
  "overview": "Updated overview..."
}

Get Version History

GET /specifications/:spec_id/versions?limit=20&offset=0
Authorization: Bearer <token>

Get Version Diff

GET /specifications/:spec_id/versions/:version_id/diff?compare_to=<previous_version_id>
Authorization: Bearer <token>

Rollback to Previous Version

POST /specifications/:spec_id/rollback
Content-Type: application/json
Authorization: Bearer <token>

{
  "target_version_id": "<version_uuid>",
  "reason": "Reverting unintended changes"
}

Configuration

Environment Variables

See .env.example for all available configuration options.

Core Settings

  • NODE_ENV: Environment (development/production)
  • PORT: Server port (default: 3000)
  • SERVICE_URL: Public service URL

API Tokens

  • NOTION_API_TOKEN: Notion integration token (required)
  • NOTION_DATABASE_ID: Notion database ID (required)
  • OPENSPEC_API_TOKEN: OpenSpec API token (optional)

Feature Flags

  • AI_GENERATION_ENABLED: Enable/disable AI generation (default: true)
  • AUTO_VALIDATION_ENABLED: Enable/disable auto-validation (default: true)
  • VERSION_HISTORY_ENABLED: Enable/disable version tracking (default: true)
  • REVIEW_WORKFLOW_ENABLED: Enable/disable review workflows (default: false)

Security

  • JWT_SECRET: Secret for JWT token signing (change in production!)
  • JWT_EXPIRY: Token expiration time (default: 1h)

Rate Limiting

  • RATE_LIMIT_WINDOW_MS: Rate limit window in milliseconds
  • RATE_LIMIT_MAX_REQUESTS: Max requests per window

Project Structure

.
├── src/
│   ├── adapters/           # External service adapters
│   │   ├── notion-adapter.ts
│   │   └── openspec-client.ts
│   ├── api/               # API route handlers
│   │   ├── specifications.ts
│   │   ├── generation.ts
│   │   └── health.ts
│   ├── components/        # Core business logic
│   │   ├── validation-engine.ts
│   │   └── version-manager.ts
│   ├── config/           # Configuration management
│   │   └── index.ts
│   ├── middleware/       # Express middleware
│   │   ├── auth.ts
│   │   ├── error-handler.ts
│   │   ├── rate-limit.ts
│   │   └── request-logger.ts
│   ├── models/           # Data models (future)
│   ├── types/            # TypeScript type definitions
│   │   └── index.ts
│   ├── utils/            # Utility functions
│   │   ├── errors.ts
│   │   ├── logger.ts
│   │   ├── retry.ts
│   │   └── validators.ts
│   └── server.ts         # Main application entry point
├── .env.example          # Environment variables template
├── .gitignore
├── Dockerfile           # Docker container definition
├── docker-compose.yml   # Multi-container Docker setup
├── jest.config.js       # Jest test configuration
├── package.json         # Dependencies and scripts
├── README.md           # This file
├── SPECIFICATION.md    # Detailed specification document
└── tsconfig.json       # TypeScript configuration

Development

Code Style

This project uses ESLint for code linting:

npm run lint
npm run lint:fix

Testing

Run tests with coverage:

npm test
npm run test -- --coverage

Watch mode for development:

npm run test:watch

Building

Compile TypeScript to JavaScript:

npm run build

The compiled output will be in the dist/ directory.

Deployment

Podman Deployment (Recommended for Production)

Rootless Production Deployment:

  1. Build the container image:

    make build
    # or
    podman build -f Containerfile -t nos-integration:latest .
  2. Run with podman-compose:

    make up
    # or
    podman-compose up -d
  3. Enable systemd for auto-start (rootless):

    make enable-systemd

    This creates user-level systemd services that start on user login.

  4. Check service health:

    make health

Security Features Enabled:

  • ✅ Rootless containers (no root daemon)
  • ✅ Non-root user inside container (UID 1000)
  • ✅ No new privileges flag
  • ✅ Read-only root filesystem where possible
  • ✅ Temporary filesystems with noexec, nosuid
  • ✅ SELinux labels on volumes (:Z flag)
  • ✅ Security scanning with make scan

Docker Deployment (Alternative)

  1. Build the Docker image:

    docker build -f Dockerfile -t nos-integration:latest .
  2. Run with Docker Compose:

    docker-compose up -d

Production Considerations

  1. Container Security:

    • Use Podman rootless mode in production
    • Regularly scan images: make scan
    • Keep base images updated
    • Use specific image tags, not :latest
  2. Environment Variables: Never commit .env files. Use secrets management.

  3. JWT Secret: Generate a strong random secret for production

    openssl rand -base64 32
  4. API Tokens: Rotate Notion and OpenSpec tokens regularly (90 days recommended)

  5. HTTPS: Always use HTTPS in production (reverse proxy with Caddy/nginx)

  6. Rate Limiting: Adjust rate limits based on your usage patterns

  7. Monitoring: Set up monitoring and alerting (Datadog, CloudWatch, etc.)

  8. Logging: Configure centralized logging for production

  9. Backups:

    • Notion serves as the source of truth
    • Backup volumes: make backup-volumes
    • Consider backing up audit logs
  10. Systemd Integration (Podman only):

    # Generate and enable systemd service
    make enable-systemd
    
    # Check status
    systemctl --user status container-nos-integration.service
    
    # Enable linger for non-logged-in user
    loginctl enable-linger $USER

Troubleshooting

Common Issues

1. Notion API Connection Failed

  • Verify your NOTION_API_TOKEN is correct
  • Ensure the integration has access to your database
  • Check that NOTION_DATABASE_ID matches your database

2. OpenSpec API Not Available

  • The service will fall back to local validation if OpenSpec is unavailable
  • Check OPENSPEC_API_TOKEN is valid
  • Verify OPENSPEC_API_URL is correct

3. Rate Limiting Issues

  • Adjust RATE_LIMIT_WINDOW_MS and RATE_LIMIT_MAX_REQUESTS
  • Consider implementing user-specific rate limits
  • Check if multiple instances are sharing the same rate limiter

4. Authentication Errors

  • Ensure JWT tokens are properly formatted
  • Check JWT_SECRET matches between token generation and verification
  • Verify token hasn't expired

5. Podman-Specific Issues

  • Port binding errors: Rootless Podman can't bind to ports < 1024 without configuration
  • Volume permissions: Use :Z flag for SELinux systems: -v ./data:/data:Z
  • Network connectivity: Check with podman network inspect nos-network
  • See PODMAN.md for detailed Podman troubleshooting

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues and questions:

  • Review the SPECIFICATION.md for detailed requirements
  • Check existing GitHub issues
  • Create a new issue with detailed information

Roadmap

See SPECIFICATION.md Section 20: Future Considerations for planned features including:

  • Real-time Notion webhooks integration
  • Advanced analytics dashboard
  • Specification templates library
  • Custom validation rules builder
  • Mobile app support
  • Multi-workspace federation

Acknowledgments

About

notion + openspec integration

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors