Skip to content

Latest commit

 

History

History
795 lines (661 loc) · 24.9 KB

File metadata and controls

795 lines (661 loc) · 24.9 KB

Software Catalog Specification

Version: 3.0 Date: 2025-12-29 Status: Implementation Ready (Schema.org Aligned)


1. Overview

This specification defines a software catalog system for tracking software products, vendors, categories, risk assessments, and alternatives. The catalog uses Schema.org vocabulary for field naming and JSON-LD structure.

Design goals:

  1. Aggregate data from multiple sources (euro-stack, switching.software, CNCF Landscape, Cloud Service Map)
  2. Support digital sovereignty assessments (NDSI framework)
  3. Map non-European software to European alternatives
  4. Enable multi-dimensional categorization (technical, business, developer, platform taxonomies)
  5. Support multiple user personas with persona-specific filtering
  6. Schema.org alignment for interoperability and semantic web compatibility

2. Schema.org Alignment

All data files use Schema.org vocabulary:

Entity Schema.org Type Wrapper
Products SoftwareApplication ItemList
Vendors Organization ItemList
Assessments Review + Rating ItemList
Alternatives - ItemList
Taxonomies DefinedTerm DefinedTermSet

JSON-LD Wrapper Structure

Products, Vendors, Alternatives, Assessments:

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [...]
}

Taxonomies:

{
  "@context": "https://schema.org",
  "@type": "DefinedTermSet",
  "hasDefinedTerm": [...]
}

3. Data Model

3.1 Entity Relationship Diagram

┌─────────────────────┐
│  software-vendors   │
│─────────────────────│
│  identifier (PK)    │
│  name               │
│  addressCountry     │
│  url                │
│  dateModified       │
└─────────┬───────────┘
          │ 1
          │
          │ manufacturer (FK)
          │
          │ *
┌─────────▼───────────┐       ┌─────────────────────┐
│  software-products  │       │ software-alternatives│
│─────────────────────│       │─────────────────────│
│  identifier (PK)    │◄──────│  identifier (FK)    │
│  name               │       │  isSimilarTo[]      │──┐
│  description        │       │  sources[]          │  │
│  url                │       │  dateModified       │  │
│  manufacturer (FK)  │       └─────────────────────┘  │
│  applicationCategory│                                │
│  isOpenSource       │◄───────────────────────────────┘
│  selfHostable       │       (isSimilarTo references products)
│  dataPortability    │
│  tags[]             │
│  repository{}       │
│  sources[]          │
│  dateModified       │
└─────────┬───────────┘
          │ 1
          │
          │ itemReviewed (FK)
          │
          │ *
┌─────────▼───────────┐       ┌─────────────────────┐
│ software-assessments│       │  software-taxonomy  │
│─────────────────────│       │─────────────────────│
│  itemReviewed (FK)  │       │  termCode (PK)      │
│  framework          │       │  name               │
│  version            │       │  description        │
│  datePublished      │       │  icon               │
│  reviewRating{}     │       │  dateModified       │
│  riskLevel          │       └─────────────────────┘
│  scores{}           │       (4 files: technical, business, developer, platforms)
│  negativeNotes[]    │
│  suggestedActions[] │
│  citation[]         │
│  dateModified       │
└─────────────────────┘

3.2 File Structure

catalog/
├── software-products.json            # All products (EU and non-EU)
├── software-vendors.json             # All vendors
├── software-alternatives.json        # Product → alternatives mapping
├── software-assessments.json         # Risk/sovereignty assessments
├── software-taxonomy-technical.json  # Technical categories (59)
├── software-taxonomy-business.json   # Business function categories (9)
├── software-taxonomy-developer.json  # Developer/cloud categories (52)
├── software-taxonomy-platforms.json  # Platform categories (10)
├── software-personas.json            # User personas with filters (9)
├── software-tags.json                # Cross-cutting tags (34)
│
└── schema/
    ├── software-products.schema.json
    ├── software-vendors.schema.json
    ├── software-alternatives.schema.json
    ├── software-assessments.schema.json
    ├── software-taxonomy.schema.json
    └── framework.schema.json

data/software/                            # Deliverable output for Hugo/PWA
├── products.json                         # Enriched with vendor details, alternatives
├── products-lite.json                    # Minimal data for PWA filtering
├── taxonomies.json                       # Merged taxonomies with product counts
└── schemas/                              # Output validation schemas

scraped/
├── raw/                              # Cached HTML from scrapers
└── normalized/                       # Normalized scraper output
    ├── euro-stack.json
    ├── euro-stack-alternatives.json
    ├── switching-software.json
    └── switching-software-alternatives.json

4. Schemas

4.1 Products Schema

Uses Schema.org SoftwareApplication type.

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "SoftwareApplication",
      "identifier": "nextcloud",
      "name": "Nextcloud",
      "description": "Open source file sync and collaboration platform",
      "descriptionSource": {
        "sourceName": "switching.software",
        "sourceUrl": "https://switching.software/replace/google-drive/",
        "license": "CC-BY-SA-4.0",
        "fetchedAt": "2025-12-29T12:54:05.607Z"
      },
      "url": "https://nextcloud.com",
      "manufacturer": "nextcloud",
      "applicationCategory": {
        "technical": ["collaboration", "cloud-storage"],
        "business": ["collaboration"],
        "developer": ["object-storage", "file-storage"]
      },
      "tags": ["open-source", "self-hosted", "docker", "gdpr-compliant", "eu-hosted"],
      "isOpenSource": true,
      "selfHostable": true,
      "dataPortability": "full",
      "repository": {
        "url": "https://github.com/nextcloud/server"
      },
      "sources": [
        {
          "sourceName": "euro-stack",
          "sourceUrl": "https://euro-stack.com/solutions/nextcloud",
          "fetchedAt": "2025-12-23T09:48:42.289Z"
        },
        {
          "sourceName": "switching.software",
          "sourceUrl": "https://switching.software/replace/google-drive/",
          "fetchedAt": "2025-12-29T12:54:05.607Z"
        }
      ],
      "dateModified": "2025-12-29"
    }
  ]
}

Field Reference:

Field Required Schema.org Description
@type Yes SoftwareApplication Type annotation
identifier Yes identifier Unique ID (kebab-case)
name Yes name Product name
description Yes description Short description
descriptionSource No - Attribution for description (sourceName, sourceUrl, license, fetchedAt)
manufacturer Yes manufacturer Reference to vendor identifier
isOpenSource Yes - Boolean
dateModified Yes dateModified Date (YYYY-MM-DD)
url No url Official website
repository No codeRepository Repository info
applicationCategory No applicationCategory Taxonomy assignments (technical, business, developer)
maturity No - Maturity level (1=experimental, 2=incubating, 3=stable) with source info
targetAudience No - Target job roles (developer, platform-engineer, sre, etc.)
tags No - Cross-cutting tags for filtering
links No - Related links (blog, chat, documentation, video, statistics)
selfHostable No - Can be self-hosted
dataPortability No - none/partial/full
sources No - Array of catalog sources where product was found

4.2 Vendors Schema

Uses Schema.org Organization type.

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "Organization",
      "identifier": "nextcloud",
      "name": "Nextcloud GmbH",
      "addressCountry": "DE",
      "url": "https://nextcloud.com",
      "dateModified": "2025-12-29"
    }
  ]
}

Field Reference:

Field Required Schema.org Description
@type Yes Organization Type annotation
identifier Yes identifier Unique vendor ID
name Yes name Company name
addressCountry Yes addressCountry ISO 3166-1 alpha-2 code
url Yes url Company website
dateModified Yes dateModified Date (YYYY-MM-DD)

4.3 Alternatives Schema

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "identifier": "ms-teams",
      "isSimilarTo": ["whereby", "element", "mattermost", "pexip"],
      "sources": [
        {
          "sourceName": "euro-stack",
          "sourceUrl": "https://euro-stack.com/alternatives/microsoft-teams",
          "fetchedAt": "2025-12-23T09:48:43.750Z"
        }
      ],
      "dateModified": "2025-12-29"
    }
  ]
}

Field Reference:

Field Required Schema.org Description
identifier Yes identifier Product identifier
isSimilarTo Yes isSimilarTo Alternative product IDs
dateModified Yes dateModified Date (YYYY-MM-DD)
sources No - Data sources

4.4 Assessments Schema

Uses Schema.org Review and Rating types.

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "Review",
      "itemReviewed": "azure",
      "framework": "ndsi",
      "version": "1.0",
      "datePublished": "2025-12-19",
      "reviewRating": {
        "@type": "Rating",
        "ratingValue": 2.08,
        "bestRating": 3,
        "worstRating": 0
      },
      "riskLevel": 2,
      "scores": {
        "strategic": { "score": 3, "rationale": "US company" },
        "legal": { "score": 3, "rationale": "Subject to CLOUD Act" },
        "data": { "score": 1, "rationale": "Norway regions available" }
      },
      "negativeNotes": [
        "Subject to US CLOUD Act",
        "Strategic dependency on US provider"
      ],
      "suggestedActions": [
        {
          "title": "Use Norway regions",
          "description": "Configure for Norway East/West regions",
          "effort": "low",
          "impact": "medium"
        }
      ],
      "citation": [
        "https://azure.microsoft.com/en-us/explore/trusted-cloud/"
      ],
      "dateModified": "2025-12-29"
    }
  ]
}

Field Reference:

Field Required Schema.org Description
@type Yes Review Type annotation
itemReviewed Yes itemReviewed Product identifier
framework Yes - Framework ID (ndsi, eu-csf)
version Yes - Framework version
datePublished Yes datePublished Assessment date
reviewRating Yes reviewRating Rating object
riskLevel Yes - Integer risk level
dateModified Yes dateModified Last updated
scores No - Dimension scores
negativeNotes No negativeNotes Key concerns
suggestedActions No potentialAction Mitigations
citation No citation Source URLs

4.5 Taxonomy Schema

Uses Schema.org DefinedTermSet and DefinedTerm types.

{
  "@context": "https://schema.org",
  "@type": "DefinedTermSet",
  "hasDefinedTerm": [
    {
      "@type": "DefinedTerm",
      "termCode": "collaboration",
      "name": "Collaboration",
      "description": "Software for team communication and information sharing",
      "icon": "files",
      "dateModified": "2025-12-29"
    }
  ]
}

Field Reference:

Field Required Schema.org Description
@type Yes DefinedTerm Type annotation
termCode Yes termCode Unique ID (kebab-case)
name Yes name Display name
description Yes description Category description
dateModified Yes dateModified Date (YYYY-MM-DD)
icon No - Icon identifier

5. Taxonomy Strategy

5.1 Multi-dimensional Taxonomy

Products can be categorized across multiple dimensions:

Dimension File Count Purpose Example Values
technical software-taxonomy-technical.json 59 What the software does devops, crm, monitoring
business software-taxonomy-business.json 9 Business function sales, hr, finance
developer software-taxonomy-developer.json 52 Cloud/dev alternatives relational-database, serverless-functions
platforms software-taxonomy-platforms.json 10 Deployment platform online, windows, linux

5.2 Developer Taxonomy

The developer taxonomy provides granular categories for finding alternatives to cloud services:

Parent Categories
database relational-database, document-database, graph-database, key-value-store, time-series-database, vector-database, search-engine
messaging message-queue, event-streaming, pubsub
compute serverless-functions, container-orchestration, container-registry, container-runtime, cron-scheduler
storage object-storage, block-storage, file-storage
networking api-gateway, service-mesh, load-balancer, dns, vpn
security secrets-management, identity-provider, certificate-management, waf
observability metrics-monitoring, log-management, distributed-tracing, alerting
devops ci-cd, gitops, infrastructure-as-code, artifact-repository, source-control
ai-ml ml-platform, llm-inference, feature-store
data workflow-orchestration, etl, data-warehouse, data-lake

5.3 Category Assignment

Categories are assigned in the applicationCategory field:

{
  "identifier": "postgresql",
  "applicationCategory": {
    "technical": ["database"],
    "developer": ["relational-database"],
    "platforms": ["linux", "windows", "macos"]
  }
}

6. User Personas

6.1 Persona Definition

The catalog supports 9 user personas, each with specific filtering criteria:

Persona Description Primary Taxonomy
developer Cloud service alternatives, frameworks developer
business CRM, HR, finance tools business
technical Infrastructure, monitoring, security technical
privacy-conscious Ethical alternatives, no tracking (cross-cutting)
self-hoster Own infrastructure, Docker/K8s (cross-cutting)
sovereignty EU-based, GDPR compliant (cross-cutting)
enterprise Compliance, SLAs, vendor assessment (cross-cutting)
cost-conscious Free/OSS alternatives (cross-cutting)
end-user Everyday apps business

6.2 Persona Structure

{
  "@type": "DefinedTerm",
  "termCode": "developer",
  "name": "Developer",
  "description": "Software developers looking for alternatives to cloud services",
  "taxonomy": "software-taxonomy-developer.json",
  "filterCriteria": {
    "preferTags": ["open-source", "self-hosted", "api", "sdk"],
    "preferCategories": ["database", "messaging", "compute", "devops"],
    "showFields": ["repository", "applicationCategory.platforms", "isOpenSource"]
  },
  "exampleQueries": [
    "Alternative to AWS Lambda",
    "Open source Kafka replacement"
  ]
}

7. Cross-Cutting Tags

7.1 Tag Categories

Tags enable filtering across all taxonomies:

Category Tags
Licensing open-source, free-tier, source-available
Deployment self-hosted, saas, docker, kubernetes, helm
Privacy privacy-focused, no-tracking, end-to-end-encrypted, zero-knowledge
Compliance gdpr-compliant, hipaa-compliant, soc2, iso27001
Sovereignty eu-based, eu-hosted, data-residency
Enterprise enterprise, sla, support, sso, audit-log
Integration api, sdk, webhooks, s3-compatible
Maturity cncf-graduated, cncf-incubating, cncf-sandbox

7.2 Tag Usage

{
  "identifier": "minio",
  "tags": ["open-source", "self-hosted", "s3-compatible", "docker", "kubernetes"]
}

8. Alternatives System

8.1 Design

Alternatives are stored in a separate file (software-alternatives.json), enabling:

  • Bidirectional queries
  • Multiple data sources per relationship
  • Clean separation of concerns

8.2 Bidirectional Relationships

The enriched output (data/software/products.json) includes:

  • isSimilarTo: Products this can replace
  • isAlternativeFor: Products that list this as alternative
{
  "identifier": "pexip",
  "isSimilarTo": ["ms-teams", "zoom"],
  "isAlternativeFor": ["ms-teams", "zoom", "google-meet"]
}

8.3 Query Examples

// "What are alternatives to MS Teams?"
const alts = alternatives.find(a => a.identifier === 'ms-teams');
// → { isSimilarTo: ["whereby", "element", ...] }

// "What is Whereby an alternative to?"
const altTo = alternatives.filter(a => a.isSimilarTo.includes('whereby'));
// → [{ identifier: "ms-teams" }, { identifier: "zoom" }, ...]

9. Enriched Output

The build process (npm run catalog:output) generates data/software/products.json with:

  1. Vendor details merged inline as full Organization objects
  2. Bidirectional alternatives calculated from alternatives file
  3. sourceCount - number of catalogs the product appears in (popularity signal)
  4. descriptionSource - attribution for description text
  5. Full Schema.org JSON-LD structure

Example:

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "SoftwareApplication",
      "identifier": "pexip",
      "name": "Pexip",
      "description": "Norwegian video conferencing solution",
      "descriptionSource": {
        "sourceName": "euro-stack",
        "sourceUrl": "https://euro-stack.com/solutions/pexip",
        "license": "verify"
      },
      "isOpenSource": false,
      "sourceCount": 2,
      "dateModified": "2025-12-29",
      "manufacturer": {
        "@type": "Organization",
        "identifier": "pexip",
        "name": "Pexip Holding ASA",
        "url": "https://pexip.com",
        "address": {
          "@type": "PostalAddress",
          "addressCountry": "NO"
        }
      },
      "isSimilarTo": ["ms-teams", "zoom"],
      "isAlternativeFor": ["ms-teams", "zoom", "google-meet"],
      "sources": [
        { "sourceName": "euro-stack" },
        { "sourceName": "switching.software" }
      ]
    }
  ]
}

The sourceCount field indicates how many different catalogs list this product. Higher counts suggest more well-known/popular software.


10. Scraper Field Coverage

Different data sources provide different fields. This table shows which optional fields each scraper populates:

Field CNCF cloud-service-map euro-stack switching.software
maturity - -
targetAudience - - -
tags - - -
links - - -
selfHostable - - -
repository - ✓* ✓*

*euro-stack uses placeholder URLs for open source products; switching.software only sets repository if homepage is on github/gitlab/codeberg.

Maturity Mapping

The maturity field uses a 3-level scale for filtering:

Level Label Description
1 Experimental Early stage, unstable API
2 Incubating Growing adoption, stabilizing
3 Stable Production-ready

Source-specific mappings:

Source Level 1 Level 2 Level 3
CNCF Sandbox Incubating Graduated
cloud-service-map - - GA (all products)

Cloud services from major providers (AWS, Azure, GCP) are set to level 3 (stable) since they are production-ready GA services.

Target Audience

The targetAudience field uses normalized job roles. CNCF personas are mapped to these values:

  • platform-engineer, developer, sre, devops, devsecops
  • architect, security-engineer, network-engineer
  • data-engineer, ml-engineer, cluster-admin
  • database-admin, system-admin, it-operations, compliance-officer

Links

The links array contains typed links:

Type Description
blog Project blog
chat Community chat (Slack, Discord)
documentation Official docs
video Intro/demo video
statistics DevStats or similar
repository Source code repository
social Social media
other Other links

11. ID Conventions

11.1 ID Format

  • Format: kebab-case (lowercase, hyphens)
  • Pattern: [a-z0-9]+(-[a-z0-9]+)*
  • Examples: ms-teams, nextcloud, aws-s3

11.2 ID Mapping

Different sources may use different IDs. The canonical registry maps aliases to canonical IDs:

  • catalog/canonical-products.json
{
  "microsoft-teams": {
    "name": "Microsoft Teams",
    "aliases": ["ms-teams"]
  },
  "aws": {
    "name": "Amazon Web Services",
    "aliases": ["amazon-web-services-aws"]
  }
}

12. Validation

Validate all data files against schemas:

npm run catalog:validate

Expected output:

✓ software-products.json
✓ software-vendors.json
✓ software-assessments.json
✓ software-taxonomy-business.json
✓ software-taxonomy-technical.json
✓ software-taxonomy-platforms.json
✓ software-taxonomy-developer.json
✓ software-personas.json
✓ software-tags.json
✓ software-alternatives.json

Results: 10 passed, 0 failed

13. Current Statistics

Metric Count
Total products 3,245
Total vendors 1,940
Alternative mappings 789
Technical categories 59
Business categories 9
Developer categories 52
Platform categories 10
User personas 9
Cross-cutting tags 34
Products with maturity 790

14. Field Migration Reference

Schema.org alignment changed these field names:

Products

Old Field New Field (Schema.org)
id identifier
vendor_id manufacturer
open_source isOpenSource
updated_at dateModified
taxonomies applicationCategory

Vendors

Old Field New Field (Schema.org)
id identifier
country addressCountry
website url
updated_at dateModified
country_name (removed)

Alternatives

Old Field New Field (Schema.org)
product_id identifier
alternative_ids isSimilarTo
updated_at dateModified

Assessments

Old Field New Field (Schema.org)
product_id itemReviewed
date datePublished
score reviewRating.ratingValue
key_concerns negativeNotes
mitigations suggestedActions
sources citation
updated_at dateModified

Taxonomies

Old Field New Field (Schema.org)
id termCode
updated_at dateModified
Wrapper: categories Wrapper: hasDefinedTerm

Appendix: Glossary

Term Definition
Schema.org Vocabulary for structured data on the web
JSON-LD JSON for Linking Data - structured data format
identifier Unique ID for an entity (Schema.org property)
manufacturer Producer/creator of software (Schema.org property)
isSimilarTo Relationship indicating alternatives (Schema.org property)
DefinedTermSet Collection of defined terms (Schema.org type)
NDSI Nasjonal Digital Suverenitet Index - sovereignty risk framework